传送门:点击打开链接
B - B
Gym - 101532BYou are given an array a consisting of n elements a1, a2, ..., an. Array a has a special property, which is:
You are given the array a with some lost elements from it, each lost element is replaced by -1. Your task is to find all the lost elements again, can you?
Input
The first line contains an integer T, where T is the number of test cases.
The first line of each test case contains two integers n and m (1 ≤ n ≤ 1000) (1 ≤ m ≤ 109), where n is the size of the array, and m is the described modulus in the problem statement.
The second line of each test case contains n integers a1, a2, ..., an ( - 1 ≤ ai < m), giving the array a. If the ith element is lost, then ai will be -1. Otherwise, ai will be a non-negative integer less than m.
It is guaranteed that the input is correct, and there is at least one non-lost element in the given array.
OutputFor each test case, print a single line containing n integers a1, a2, ..., an, giving the array a after finding all the lost elements.
It is guaranteed that an answer exists for the given input.
Example4 5 10 1 2 3 4 5 4 10 7 -1 9 -1 6 7 5 -1 -1 1 2 3 6 10 5 -1 7 -1 9 0
1 2 3 4 5 7 8 9 0 5 6 0 1 2 3 5 6 7 8 9 0
As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.
题意:
给你一个规律,然后给你一些已知的数,让你求一些确实的数。
思路:
标记下来确定的数的位置,然后向右遍历求值,向左遍历求值即可。
代码:
#include <bits/stdc++.h> using namespace std; int n,m; int a[100005]; int pos; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=n;i++) { if(a[i]!=-1) { pos=i; break; } } for(int i=pos+1;i<=n;i++) { a[i] = (a[i-1] + 1) % m; } for(int i=pos-1;i>=1;i--) { a[i] =(a[i+1] - 1 + m ) % m; } for(int i=1;i<=n;i++) { printf("%d ",a[i]); } printf("\n"); } return 0; }
D - D
Gym - 101532DYousef has a string s that is used to build a magical string w by repeating the string s infinitely many times. For example, if s = aabbb , then w = aabbbaabbbaabbbaabbb....
Mohammad always claims that his memory is strong, and that his ability to count is very high, so Yousef decided to hold a test for Mohammad, in order to know the truth of his claims.
Yousef will give Mohammad q queries, such that each query consisting of two integers l and r, and a lowercase English letter c. The answer of each query is how many times the letter c appears between the lth and rth letters in string w.
Mohammad must answer all the queries correctly, in order to proof his claims, but currently he is busy finishing his meal. Can you help Mohammad by answering all queries?
Input
The first line contains an integer T, where T is the number of test cases.
The first line of each test case contains two integers n and q (1 ≤ n ≤ 104) (1 ≤ q ≤ 105), where n is the length of string s, and q is the number of queries.
The second line of each test case contains the string s of length n consisting only of lowercase English letters.
Then q lines follow, each line contains two integers l and r and a lowercase English letter c (1 ≤ l ≤ r ≤ 109), giving the queries.
OutputFor each query, print a single line containing how many times the letter c appears between the lth and rth letters in string w.
Example1 8 5 abcabdca 1 8 c 1 15 b 4 9 a 5 25 d 2 7 c
2 4 3 3 2
As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.
思路:
这个题耽误了很长时间,就是因为一开始没有想到提前记录一下在i个位置上,他前面有多少个和它相同的字符。具体来说:
先用一个num[26][n]的二维数组,记录第i个字符在j之前出现的次数,这样只需处理区间内有多少个给定的字符串,然后在单独处理一下两边的边界即可,如何使边界处理起来比较方便?这就是这个题目关键,我们要求区间l~r,可以用区间1~r减去区间1~l-1即可。
代码:
#include <iostream> #include <map> #include <cstring> #include <cstdio> using namespace std; typedef long long LL; int n,q; char s[10005]; int num[26][10005]; //i个字母在j位置前出现次数 int main() { int T; scanf("%d",&T); while(T--) { scanf("%d %d",&n,&q); scanf("%s",&s); for (int i=0;i<26 ; i++) { int nnn=0; for(int j=0;j<n;j++) { if(s[j]-'a' == i) { nnn++; } num[i][j+1] = nnn; //此处j+1是为了使字符从1开始,否则比较容易乱 } //cout<<nnn<<"---"<<endl; } while(q--) { LL l, r ; char ch; scanf("%lld %lld %c",&l,&r,&ch); LL sum_l = 0; LL sum_r = 0; l--; sum_l = (l / n) * num[ch-'a'][n] + num[ch-'a'][l % n]; //1-l-1的某个字符的个数 sum_r = (r / n) * num[ch-'a'][n] + num[ch-'a'][r % n]; //1-r的某个字符的个数 /* cout<<"l/n="<<l/n<<endl; cout<<"r/n="<<r/n<<endl; cout<<"l%n="<<(l+n)%n<<endl; cout<<"r%n="<<(r+n)%n<<endl; cout<<"sum_l="<<sum_l<<endl; cout<<"sum_r="<<sum_r<<endl;*/ LL sum = sum_r - sum_l; //相减即为结果 printf("%lld\n",sum); } } return 0; }
F - F
Gym - 101532GAlaa sometimes feels bored at work, so at such times she starts playing with a beautiful array a consisting of n integers a1, a2, ..., an.
Alaa starts counting the number of magical indices in the array a. An index x is said to be magical if it satisfying the following rules:
- 1 < x < n
- ay ≤ ax, for each y (1 ≤ y < x).
- ax ≤ az, for each z (x < z ≤ n).
Can you help Alaa by counting the number of magical indices in the array a.
InputThe first line contains an integer T, where T is the number of test cases.
The first line of each test case contains an integer n (1 ≤ n ≤ 106), where n is the size of the array a.
The second line of each test case contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106), giving the array a.
OutputFor each test case, print a single line containing the number of magical indices in the array a.
Example2 8 2 1 3 4 6 5 7 9 6 4 2 7 9 8 10
3 1
As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.
思路:
首先,正向求一遍最大,然后再反向求一遍最小,最后在每个元素位置进行一下判断即可
代码:
#include <bits/stdc++.h> #define INF 0x7f7f7f7f #define ll long long #define mod 1000000007 using namespace std; int dpf[1000010],dpb[1000010]; int a[1000010]; int main() { int t; scanf("%d",&t);//cin>>t; while(t--) { int n,i,res=0; scanf("%d",&n);//cin>>n; scanf("%d",&a[0]);//cin>>a[0]; dpf[0]=a[0]; for(i=1;i<n;i++) { scanf("%d",&a[i]);//cin>>a[i]; dpf[i]=max(a[i],dpf[i-1]); //正像最大 } dpb[n-1]=a[n-1]; for(i=n-2;i>=0;i--) { dpb[i]=min(a[i],dpb[i+1]); //反向最小 } for(i=1;i<n-1;i++) { if(a[i]>=dpf[i-1]&&a[i]<=dpb[i+1]) //关键 { res++; } } printf("%d\n",res);//cout<<res<<endl; } return 0; }
G - G
Gym - 101532HHusam has a lot of free time, so he is using this time in repairing corrupted binary images.
A Binary image can be represented as 2-dimensional array consisting of n rows, each of which is divided into m columns. The rows are numbered from 1 to n from top to bottom, and the columns are numbered from 1 to m from left to right. Each cell is identified by a pair (x, y), which means that the cell is located at row x and column y. The possible values in the binary images are either zero or one.
A binary image is good if all cells in the first row, last row, first column, and last column are ones. Otherwise, the binary image is corrupted. If the binary image is corrupted, Husam will fix it.
Husam wants to fix the image with the minimum number of moves, such that in each move he can swap the values at two different cells.
Can you help Husam by calculating the minimum number of required moves to fix the image?
Input
The first line contains an integer T, where T is the number of test cases.
The first line of each test case contains two integers n and m (3 ≤ n, m ≤ 50), where n is the number of rows in the binary image, and m is the number of columns in each row.
Then n lines follow, each line contains m characters, giving the binary image. All values in the binary image are either zero or one.
OutputFor each test case, print a single line containing -1 if Husam cannot fix the binary image. Otherwise, print the minimum number of required moves to fix the image.
Example3 3 3 111 101 111 4 4 1111 0111 1000 1111 4 5 10101 01010 10101 01010
0 2 -1
In the first test case, the image is good. In the second test case, Husam needs to swap the values of cells (2, 1) and (2, 2), and swap the values of cells (2, 3) and (3, 4), in order to fix the image.
移动多少步使得第一行第一列最后一行最后一列均为1,注意移动可以任意两个位置(这样问题就很简单)
思路:记录一下,判断一下1的个数就可
代码:
#include <bits/stdc++.h> using namespace std; int n,m; char s[100]; int main() { int T; cin>>T; while(T--) { cin>>n>>m; int num_z = 0; int num_o = 0; bool flag = true; for(int i = 1; i <= n; i++) { cin>>s; for(int j=0;j<m;j++) { if(i==1 || j==0 || i==n || j==m-1) { if(s[j]=='0') { flag = false; num_o ++; } } if(s[j] == '1') num_z++; } } if(flag==true) { printf("0\n"); continue; } int num = 2*n + 2*m - 4; if(num > num_z) { printf("-1\n"); continue; } printf("%d\n",num_o); } return 0; }
Since the problem set was hard, here is an easy task for you to solve.
You are given an array a consisting of n integers, and your task is to calculate the summation of the multiplication of all subsets of array a. (See the note for more clarifications)
A subset of an array a is defined as a set of elements that can be obtained by deleting zero or more elements from the original array a.
Input
The first line contains an integer T, where T is the number of test cases.
The first line of each test case contains an integer n (1 ≤ n ≤ 105), where n is the size of array a.
The second line of each test case contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106), giving the array a.
OutputFor each test case, print a single line containing the summation of the multiplication of all subsets of array a. Since this number may be too large, print the answer modulo 109 + 7.
Example3 3 1 2 3 2 3 5 1 4512
23 23 4512
As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printf instead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.
In the first test case, the array a has 6 subsets, and the answer is calculated as follow:
题意:
求一个集合里面的子集,每个子集将元素相乘,然后在将不同的子集得到的乘积加起来。
思路:
规律题,以1、2、3为例:
以1结尾:1
以2结尾:2 、1*2
以3结尾:3、1*3、2*3、1*2*3
可以看出规律:
sum[ i ] = sum [i - 1] + (a[ i ] + a[ i ] * sum [ i -1 ]);其中带括号的那一部分以为第i个元素结尾的乘积和。
代码:
#include <bits/stdc++.h> using namespace std; const int mod = 1e9+7; const int M = 100005; typedef long long LL; int a[M]; LL sum[M]; int main() { int T; int n; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1 ; i <= n ; i++) { scanf("%d",&a[i]); } sum[1] = a[1] ; for(int i = 2 ; i <= n; i++) { sum[i] = (sum[i-1] + a[i] + sum[i-1] * a[i]) % mod; } printf("%lld\n",sum[n]%mod); } return 0; }