2018.5.12—記錄菜菜的一場比賽
寫個部落格記錄一下菜鳥成長記~
賽後認真總結反思了一下,還是基礎不牢固,思路有了要麼是細節處理有問題,要麼是題意有遺漏。
A:說是規律。。反正我沒想到。。還在研究。
B:
You are given an array a consisting of n elements a1, a2, ..., an. Array a has a special property, which is:
ai = ( ai - 1 + 1) % m, for each i (1 < i ≤ n)
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.
Output
For 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.
Example
Input
4
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
Output
1 2 3 4 5
7 8 9 0
5 6 0 1 2 3
5 6 7 8 9 0
水題:就是根據一個已知的就能推其它的。
程式碼:
#include<bits/stdc++.h> using namespace std; int a[1010]; int main() { int t; int n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } int lala; for(int i=1;i<=n;i++) { if(a[i]!=-1) { a[i+1]=(a[i]+1)%m; lala=i; for(int j=i+2;j<=n;j++) { a[j]=(a[j-1]+1)%m; } break; } } for(int i=lala-1;i>=1;i--) { a[i]=a[i+1]-1; if(a[i]<0) a[i]+=m; } for(int i=1;i<=n;i++) { cout<<a[i]<<" "; } cout<<endl; } return 0; }
C:二分!!!
You are given an array a consisting of n element a1, a2, ..., an. For each element ai you must find another element aj (i ≠ j), such that the summation of ai and aj mod (109 + 7) (i.e. (ai + aj) % (109 + 7)) is as maximal as possible.
Can you help judges by solving this hard problem?
Input
The first line contains an integer T, where T is the number of test cases.
The first line of each test contains an integer n (2 ≤ n ≤ 105), where n is the size of the array a.
The second line of each test case contains n integers a1, a2, ..., an (0 ≤ ai < 109 + 7), giving the array a.
Output
For each test case, print a single line containing n space separated elements, such that the ith element is the answer to the ith element in the array a (i.e. the maximum value of (ai + aj) % (109 + 7)).
Example
Input
2
3
1 2 3
2
1000000000 1000000000
Output
4 5 5
999999993 999999993
程式碼:
就是找最接近(mod-a【i】-1)的那個數。可惜我二分沒搜好
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[100005];
struct node
{
int num,id;
bool operator<(const node &aa)const
{
if(num!=aa.num)
return num<aa.num;
return id<aa.id;
}
}b[100005];
int mod;
int main()
{
int i,j,t,n,ant;
scanf("%d",&t);
mod=1000000007;
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
b[i].num=a[i];
b[i].id=i;
}
sort(b,b+n);
for(i=0;i<n;i++)
{
if(i!=0)printf(" ");
int ans;
ans=(mod-1-a[i]+mod)%mod;
int l,r,mid;
l=0;
r=n-1;
ant=n-1;
while(l<=r)
{
mid=(l+r)>>1;
if(b[mid].num>ans)
{
r=mid-1;
}
else
{
l=mid+1;
ant=mid;
}
}
//printf("%d %d \n",ant,ans);
if(b[ant].id==i)
{
if(ant==0)
ant=n-1;
else
ant--;
}
printf("%d",(a[i]+b[ant].num)%mod);
}
printf("\n");
}
}
D:這道題就是用dp[i][j]表示到第i位,j字母出現的次數。預處理一下就好了。
Yousef 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.
Output
For each query, print a single line containing how many times the letter c appears between the lth and rth letters in string w.
Example
Input
1
8 5
abcabdca
1 8 c
1 15 b
4 9 a
5 25 d
2 7 c
Output
2
4
3
3
2
程式碼:
#include<bits/stdc++.h>
using namespace std;
int t;
char a[10005];
int dp[10005][30];
int n,q;
int l,r;
char b;
int sum;
int main()
{
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&q);
cin>>a;
dp[1][a[0]-'a']++;
for(int i=2;i<=n;i++)
{
for(int j=0;j<26;j++)
{
dp[i][j]=dp[i-1][j];
}
dp[i][a[i-1]-'a']++;
}
while(q--)
{
sum=0;
scanf("%d %d %c",&l,&r,&b);
int ans1,ans2;
ans1=dp[n][b-'a']*((l-1)/n)+dp[(l-1)%n][b-'a'];
ans2=dp[n][b-'a']*(r/n)+dp[r%n][b-'a'];
sum=ans2-ans1;
printf("%d\n",sum);
}
}
return 0;
}
E:暫時未看。聽說是折半查詢。。不會
F:好水的一道題。奈何我把大於等於當成了大於。。直到結束都沒發現讀錯題了。。
G:水題。雖然是猜的題意
H:用bfs和dp都可以。我更喜歡dp的解法。覺得還蠻好的。
自己當時居然用dfs敲了一發,tle。真是太菜了。
Universal Studios Theme Parks announced a new game named The Crazy Jumper, that is targeted problem solving fans.
In this game, there are n large boxes numbered from 1 to n from left to right, such that the ith box (1 < i ≤ n) is located to the right of the (i - 1)th box. Each box has a color, such that ci is the color of the ith box.
The goal of the game is to reach the nth box starting from the 1st box, by jumping between the boxes. The player can do one of the following jumps:
Jump one box to the right.
If the player stands at a box of color x, he/she can jump to the closest box of color x that is to the right of him, if such box exist.
Ziad will be the first one to play the game, but he is not sure whether the game is amusing or not, so he wants to finish it with the minimum number of jumps. Can you help Ziad by telling him what is the minimum number of required jumps to reach the nth box stating from the 1st box?
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 ≤ 2 × 105), where n is the number of the boxes in the game.
The second line of each test case contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 2 × 105), where ci is the color of the ith box.
Output
For each test case, print a single line containing the minimum number of required jumps to reach the nth box starting from the 1st box.
Example
Input
3
6
9 2 4 7 1 5
5
1 2 1 1 4
6
1 2 3 1 3 2
Output
5
3
2
程式碼:
#include<bits/stdc++.h>
using namespace std;
int a[200010];
int dp[200010];
int pos[200020];
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]);
}
memset(dp,0,sizeof(dp));
memset(pos,-1,sizeof(pos));
dp[1]=0;
pos[a[1]]=1;
for(int i=2;i<=n;i++)
{
dp[i]=dp[i-1]+1;
if(pos[a[i]]!=-1)
{
dp[i]=min(dp[i],dp[pos[a[i]]]+1);
}
pos[a[i]]=i;
}
cout<<dp[n]<<endl;
}
}
I:一道不是dp的dp題。這個狀態轉移方程是瞎猜的。。很不容易找了好久。。還是太菜了
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.
Output
For 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.
Example
Input
3
3
1 2 3
2
3 5
1
4512
Output
23
23
4512
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int main()
{
int t,n;
int a[100010];
long long dp[100010];
// memset(dp,0,sizeof(dp));
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
dp[0]=0;
for(int i=1;i<=n;i++)
{
dp[i]=(dp[i-1]*a[i]+dp[i-1]+a[i])%mod;
}
cout<<dp[n]<<endl;
}
return 0;
}
j:我喜歡這道題。
雖然只想出了一半,但是另一半真的是。。差一點。還是思維缺乏練習吧。
題意就是有幾個迴文串的組合。
然後有n個不同字母的組合。最多有一組是奇數才行(大於等於兩組是奇數就不可能組成迴文串)
然後就分成了兩半。
n個位置有n種排列
然後除以相同的排列組(高中知識)。具體看程式碼
An anagram is a word or phrase formed by rearranging the letters of another word or phrase, using all the original letters exactly once, such as "post", "stop", and "spot".
You are given a string s consisting of lowercase English letters. Your task is to count how many distinct anagrams of the string s are palindromes.
A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward as forward, such as "madam" or "racecar".
For example, "aabb" has 6 distinct anagrams, which are: "aabb", "abab", "abba", "baab", "baba", "bbaa". Two of the previous anagrams are palindromes, which are: "abba", "baab".
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 ≤ 20), where n is the length of the string s.
The second line of each test contains a string s of length n consisting of lowercase English letters.
Output
For each test case, print a single line containing how many distinct anagrams of the string s are palindromes.
Example
Input
5
4
aabb
6
ababbc
6
abaaba
12
babacbcbcaca
14
aaaabbcaaaabbc
Output
2
0
3
90
105
程式碼:
#include<bits/stdc++.h>
using namespace std;
map<char,int>lala;
int jie(int h)
{
int sum=1;
for(int i=h;i>=1;i--)
{
sum*=i;
}
return sum;
}
int main()
{
int t;
int n;
string h;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
cin>>h;
for(char i='a';i<='z';i++)
{
lala[i]=0;
}
for(int i=0;i<n;i++)
{
lala[h[i]]++;
}
int num=0;
for(char i='a';i<='z';i++)
{
if(lala[i]%2==1)
{
//cout<<i<<" %%%"<<endl;
num++;
}
}
//cout<<num<<" ***"<<endl;
if(num>1)
cout<<"0"<<endl;
else
{
int kaka=1;
for(char i='a';i<='z';i++)
{
lala[i]=lala[i]/2;
kaka=kaka*jie(lala[i]);
}
int pp=n/2;
int ans=jie(pp);
cout<<ans/kaka<<endl;
}
}
return 0;
}
ps:啊。有點小傷心a
這場比賽挺考驗思維的。自己還要強加練習。