Equality CF 1038A
A subsequence of string ss is a string that can be derived from ssby deleting some of its symbols without changing the order of the remaining symbols. For example, "ADE" and "BD" are subsequences of "ABCDE", but "DEA" is not.
A subsequence of ss called good if the number of occurences of each of the first kk letters of the alphabet is the same.
Find the length of the longest good subsequence of ss.
Input
The first line of the input contains integers n (1≤n≤105) andk (1≤k≤26).
The second line of the input contains the string ss of length nn. String ss only contains uppercase letters from 'A' to the kk-th letter of Latin alphabet.
Output
Print the only integer — the length of the longest good subsequence of string ss.
Examples
9 3
ACAABCCAB
6
9 4
ABCABCABC
0
Note
In the first example, "ACBCAB" ("ACAABCCAB") is one of the subsequences that has the same frequency of 'A', 'B' and 'C'. Subsequence "CAB" also has the same frequency of these letters, but doesn't have the maximum possible length.
In the second example, none of the subsequences can have 'D', hence the answer is 0.
题目意思:给你一个长度为n字符串s,让你通过删减操作,得到新字符串只包含k种字符且出现次数相等,输出新求得的字符串的长度。
解题思路:只要找到字符串s里出现次数最少的字符,将它的出现次数乘以k,还要考虑当s里字符种数小于K的情况。
1 #include<cstdio> 2 #include<cstring> 3 #include<map> 4 #include<algorithm> 5 using namespace std; 6 char s[100010]; 7 int a[30]; 8 map<char,int>mp; 9 int main() 10 { 11 int n,k,mins,counts,i,ans; 12 scanf("%d%d",&n,&k); 13 getchar(); 14 gets(s); 15 memset(a,0,sizeof(a)); 16 ans=n; 17 for(i=0; i<n; i++) 18 { 19 a[s[i]-'A']++; 20 } 21 for(i=0; i<k; i++) 22 { 23 ans=min(ans,a[i]); 24 } 25 printf("%d ",ans*k); 26 return 0; 27 }
Non-Coprime Partition CF 1038B
Find out if it is possible to partition the first nn positive integers into two non-empty disjoint sets S1S1 and S2S2 such that:
Here sum(S)sum(S) denotes the sum of all elements present in set SS andgcdgcd means thegreatest common divisor.
Every integer number from 11 to nn should be present in exactly oneof S1S1 or S2S2.
Input
The only line of the input contains a single integer nn (1≤n≤450001≤n≤45000)
Output
If such partition doesn't exist, print "No" (quotes for clarity).
Otherwise, print "Yes" (quotes for clarity), followed by two lines, describing S1S1 and S2S2 respectively.
Each set description starts with the set size, followed by the elements of the set in any order. Each set must be non-empty.
If there are multiple possible partitions — print any of them.
Examples
1
No
3
Yes 1 2 2 1 3
Note
In the first example, there is no way to partition a single number into two non-empty sets, hence the answer is "No".
In the second example, the sums of the sets are 22 and 44respectively. The gcd(2,4)=2>1gcd(2,4)=2>1, hence that is one of the possible answers.
题目意思:把1~n的所有数分成两组,使得这两组的和的最大公因数不等于1,输出这两组数。
解题思路:既然两组和的GCD不为1,那么这两组数必然存在那种类倍数的关系,那么我们可以直接利用对称性试着直接构造出这么两组数。
当n=1或者n=2时,输出No;
当n大于2时:
如果n为奇数,第一组数为最中间那个数,第二组数为除开中间数的所有数。因为最中间数的旁边两个数之和一定是它的两倍,依次取左边一个右边一个,都满足,所以除开中间那个数的所有数之和一定是中间那个数的倍数。
如果n为偶数,第一组数取第一个数和最后一个数,第二组取剩下的数。因为第一个数与最后一个数之和等于第二个数与倒数第二个数之和,也等于第三个数和倒数第三个数之和....,所以剩下的数之和一定是第一个数和最后一个数之和的倍数。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int main() 6 { 7 int n,i; 8 int x,y; 9 int a,b; 10 scanf("%d",&n); 11 a=1; 12 if(n==1||n==2) 13 { 14 printf("No "); 15 return 0; 16 } 17 printf("Yes "); 18 if(n%2) 19 { 20 x=n/2+1; 21 printf("%d %d ",a,n/2+1); 22 printf("%d",n-1); 23 for(i=1; i<=n; i++) 24 { 25 if(i!=(n/2+1)) 26 { 27 if(i==n) 28 { 29 printf(" %d ",i); 30 } 31 else 32 { 33 printf(" %d",i); 34 } 35 } 36 } 37 } 38 else 39 { 40 x=1+n; 41 printf("2 1 %d ",n); 42 printf("%d ",n-2); 43 for(i=2; i<=n-1; i++) 44 { 45 if(i==n) 46 { 47 printf(" %d ",i); 48 } 49 else 50 { 51 printf(" %d",i); 52 } 53 } 54 } 55 return 0; 56 }
Gambling CF 1038C
Two players A and B have a list of nn integers each. They both want to maximize the subtraction between their score and their opponent's score.
In one turn, a player can either add to his score any element from his list (assuming his list is not empty), the element is removed from the list afterward. Or remove an element from his opponent's list (assuming his opponent's list is not empty).
Note, that in case there are equal elements in the list only one of them will be affected in the operations above. For example, if there are elements {1,2,2,3 in a list and you decided to choose 2for the next turn, only a single instance of 2 will be deleted (and added to the score, if necessary).
The player A starts the game and the game stops when both lists are empty. Find the difference between A's score and B's score at the end of the game, if both of the players are playing optimally.
Optimal play between two players means that both players choose the best possible strategy to achieve the best possible outcome for themselves. In this problem, it means that each player, each time makes a move, which maximizes the final difference between his score and his opponent's score, knowing that the opponent is doing the same.
Input
The first line of input contains an integer nn (1≤n≤100000) — the sizes of the list.
The second line contains n integers aiai (1≤ai≤106), describing the list of the player A, who starts the game.
The third line contains n integers bibi (1≤bi≤106), describing the list of the player B.
Output
Output the difference between A's score and B's score (A−B) if both of them are playing optimally.
Examples
2 1 4 5 1
0
3 100 100 100 100 100 100
0
2 2 1 5 6
-3
Note
In the first example, the game could have gone as follows:
- A removes 5 from B's list.
- B removes 4 from A's list.
- A takes his 1.
- B takes his 1.
Hence, A's score is 1, B's score is 1 and difference is 00.
There is also another optimal way of playing:
- A removes 5 from B's list.
- B removes 4 from A's list.
- A removes 1 from B's list.
- B removes 1 from A's list.
The difference in the scores is still 0.
In the second example, irrespective of the moves the players make, they will end up with the same number of numbers added to their score, so the difference will be 0.
题目意思:A B 两人各有一组数字,每进行一轮游戏,A B 都可以选择去掉对方数组中的某一个数,或者是从自己数组中选择一个数字加到自己的分数里边,并且两人都是采取的最好的策略,每一轮游戏的时候都想使自己的分数尽可能的大,最后输出 二者的差值。
解题思路:这算是一道博弈类型的题目吧,所以肯定会有一种最优策略。先将数组中得数由大到小排序,每进行一轮游戏的时候,如果对方先现有最大数比自己现有最大数要大,就选择将对方的数去掉;否则,将该数加到自己的分数上边。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ll long long int 5 using namespace std; 6 ll a[1000010]; 7 ll b[1000010]; 8 int my_cmp(ll a,ll b) 9 { 10 return a>b; 11 } 12 int main() 13 { 14 ll n,i,j; 15 ll sum1,sum2,pos; 16 scanf("%lld",&n); 17 for(i=0; i<n; i++) 18 { 19 scanf("%lld",&a[i]); 20 } 21 for(i=0; i<n; i++) 22 { 23 scanf("%lld",&b[i]); 24 } 25 sort(a,a+n,my_cmp); 26 sort(b,b+n,my_cmp); 27 i=0,j=0; 28 sum1=0; 29 sum2=0; 30 pos=0; 31 while(i<n||j<n) 32 { 33 if(pos%2==0)///a先手,利用奇偶性质来进行每一轮比赛 34 { 35 if(a[i]>b[j]) 36 { 37 sum1+=a[i]; 38 i++; 39 } 40 else 41 { 42 j++; 43 } 44 } 45 else 46 { 47 if(b[j]>a[i]) 48 { 49 sum2+=b[j]; 50 j++; 51 } 52 else 53 { 54 i++; 55 } 56 } 57 pos++; 58 } 59 printf("%lld ",sum1-sum2); 60 return 0; 61 }
Palindrome Dance CF 1040A
A group of nn dancers rehearses a performance for the closing ceremony. The dancers are arranged in a row, they've studied their dancing moves and can't change positions. For some of them, a white dancing suit is already bought, for some of them — a black one, and for the rest the suit will be bought in the future.
On the day when the suits were to be bought, the director was told that the participants of the olympiad will be happy if the colors of the suits on the scene will form a palindrome. A palindrome is a sequence that is the same when read from left to right and when read from right to left. The director liked the idea, and she wants to buy suits so that the color of the leftmost dancer's suit is the same as the color of the rightmost dancer's suit, the 2nd left is the same as 2nd right, and so on.
The director knows how many burls it costs to buy a white suit, and how many burls to buy a black suit. You need to find out whether it is possible to buy suits to form a palindrome, and if it's possible, what's the minimal cost of doing so. Remember that dancers can not change positions, and due to bureaucratic reasons it is not allowed to buy new suits for the dancers who already have suits, even if it reduces the overall spending.
Input
The first line contains three integers nn, a, and b (1≤n≤20, 1≤a,b≤100) — the number of dancers, the cost of a white suit, and the cost of a black suit.
The next line contains nn numbers cici, ii-th of which denotes the color of the suit of the ii-th dancer. Number 0 denotes the white color, 1 — the black color, and 2 denotes that a suit for this dancer is still to be bought.
Output
If it is not possible to form a palindrome without swapping dancers and buying new suits for those who have one, then output-1. Otherwise, output the minimal price to get the desired visual effect.
Examples
5 100 1 0 1 2 1 2
101
3 10 12 1 2 0
-1
3 12 1 0 1 0
0
Note
In the first sample, the cheapest way to obtain palindromic colors is to buy a black suit for the third from left dancer and a white suit for the rightmost dancer.
In the second sample, the leftmost dancer's suit already differs from the rightmost dancer's suit so there is no way to obtain the desired coloring.
In the third sample, all suits are already bought and their colors form a palindrome.
题目意思:有n个舞者,白色衣服的价格是a,黑色衣服的价格是b,第二行有n个数字,0表穿白衣服的,1表示穿黑衣服的, 2表示还没买服装的,要使得该n个数字形成一个回文串,且花的钱最少。
解题思路:根据回文对称性,2可以看成一个未处理过的数既可以和1匹配也可以和0匹配,直接上代码吧,代码比较清楚。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 int s[110]; 7 int main() 8 { 9 int n,a,b,flag,i,j; 10 int ans; 11 scanf("%d%d%d",&n,&a,&b); 12 ans=0; 13 for(i=0; i<n; i++) 14 { 15 scanf("%d",&s[i]); 16 } 17 for(i=0; i<n; i++) 18 { 19 if(i>n-i-1)///终止 20 { 21 break; 22 } 23 if(i==n-i-1&&s[i]==2)///2出现在最中间位置时 24 { 25 ans+=min(a,b); 26 } 27 else if((s[i]==0&&s[n-i-1]==2)||(s[i]==2&&s[n-i-1]==0))///0和2对称 28 { 29 ans+=a; 30 } 31 else if((s[i]==1&&s[n-i-1]==2)||(s[i]==2&&s[n-i-1]==1))///1和2对称 32 { 33 ans+=b; 34 } 35 else if(s[i]==2&&s[n-i-1]==2)///2和2对称 36 { 37 ans+=min(a,b)*2; 38 } 39 else if(s[i]!=s[n-i-1])///出现不是对称的 40 { 41 ans=-1; 42 break; 43 } 44 } 45 printf("%d ",ans); 46 return 0; 47 }