CodeCraft-20 (Div. 2)
A. Grade Allocation
n students are taking an exam. The highest possible score at this exam is m. Let ai be the score of the i-th student. You have access to the school database which stores the results of all students.
You can change each student's score as long as the following conditions are satisfied:
All scores are integers
0≤ai≤m
The average score of the class doesn't change.
You are student 1 and you would like to maximize your own score.
Find the highest possible score you can assign to yourself such that all conditions are satisfied.
Input
Each test contains multiple test cases.
The first line contains the number of test cases t (1≤t≤200). The description of the test cases follows.
The first line of each test case contains two integers n and m (1≤n≤103, 1≤m≤105) — the number of students and the highest possible score respectively.
The second line of each testcase contains n integers a1,a2,…,an (0≤ai≤m) — scores of the students.
Output
For each testcase, output one integer — the highest possible score you can assign to yourself such that both conditions are satisfied.
Example
input
2
4 10
1 2 3 4
4 5
1 2 3 4
output
10
5
Note
In the first case, a=[1,2,3,4], with average of 2.5. You can change array a to [10,0,0,0]. Average remains 2.5, and all conditions are satisfied.
In the second case, 0≤ai≤5. You can change a to [5,1,1,3]. You cannot increase a1 further as it will violate condition 0≤ai≤m.
思路: 把所有同学的分都夺走,但注意不能超过m
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<set>
#include<map>
using namespace std;
int a[1100];
int main(){
int T;
cin>>T;
while(T--){
long long n,m;
cin>>n>>m;
long long sum=0;
for(int i=1;i<=n;++i){
cin>>a[i];
sum+=a[i];
}
cout<<min(sum,m)<<endl;
}
return 0;
}
B. String Modification
Vasya has a string s of length n. He decides to make the following modification to the string:
Pick an integer k, (1≤k≤n).
For i from 1 to n−k+1, reverse the substring s[i:i+k−1] of s. For example, if string s is qwer and k=2, below is the series of transformations the string goes through:
qwer (original string)
wqer (after reversing the first substring of length 2)
weqr (after reversing the second substring of length 2)
werq (after reversing the last substring of length 2)
Hence, the resulting string after modifying s with k=2 is werq.
Vasya wants to choose a k such that the string obtained after the above-mentioned modification is lexicographically smallest possible among all choices of k. Among all such k, he wants to choose the smallest one. Since he is busy attending Felicity 2020, he asks for your help.
A string a is lexicographically smaller than a string b if and only if one of the following holds:
a is a prefix of b, but a≠b;
in the first position where a and b differ, the string a has a letter that appears earlier in the alphabet than the corresponding letter in b.
Input
Each test contains multiple test cases.
The first line contains the number of test cases t (1≤t≤5000). The description of the test cases follows.
The first line of each test case contains a single integer n (1≤n≤5000) — the length of the string s.
The second line of each test case contains the string s of n lowercase latin letters.
It is guaranteed that the sum of n over all test cases does not exceed 5000.
Output
For each testcase output two lines:
In the first line output the lexicographically smallest string s′ achievable after the above-mentioned modification.
In the second line output the appropriate value of k (1≤k≤n) that you chose for performing the modification. If there are multiple values of k that give the lexicographically smallest string, output the smallest value of k among them.
Example
input
6
4
abab
6
qwerty
5
aaaaa
6
alaska
9
lfpbavjsm
1
p
output
abab
1
ertyqw
3
aaaaa
1
aksala
6
avjsmbpfl
5
p
1
Note
In the first testcase of the first sample, the string modification results for the sample abab are as follows :
for k=1 : abab
for k=2 : baba
for k=3 : abab
for k=4 : baba
The lexicographically smallest string achievable through modification is abab for k=1 and 3. Smallest value of k needed to achieve is hence 1.
思路: 可以发现每次操作都是将最后开始长度为K的前缀向后移动一次,因在内部反转一下。所有最终就是1~k移动到最后,正反右前面的字符数决定。n<=5000,可以暴力枚举k。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<set>
#include<map>
using namespace std;
string a,b,ans;
int main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
cin>>a;
b.clear();
ans="";
int Min;
for(int i=1;i<=n;++i){
b="";
for(int j=i-1;j<n;++j)
b+=a[j];
int t=n-i-1;
if(t%2==0) {
for(int j=0;j<i-1;++j)
b+=a[j];
}
else
for(int j=i-2;j>=0;--j){
b+=a[j];
}
if(b<ans||ans==""){
//cout<<b<<endl;
ans=b;
Min=i;
}
}
cout<<ans<<endl<<Min<<endl;
}
return 0;
}
C. Primitive Primes
It is Professor R's last class of his teaching career. Every time Professor R taught a class, he gave a special problem for the students to solve. You being his favourite student, put your heart into solving it one last time.
You are given two polynomials f(x)=a0+a1x+⋯+an−1xn−1 and g(x)=b0+b1x+⋯+bm−1xm−1, with positive integral coefficients. It is guaranteed that the cumulative GCD of the coefficients is equal to 1 for both the given polynomials. In other words, gcd(a0,a1,…,an−1)=gcd(b0,b1,…,bm−1)=1. Let h(x)=f(x)⋅g(x). Suppose that h(x)=c0+c1x+⋯+cn+m−2xn+m−2.
You are also given a prime number p. Professor R challenges you to find any t such that ct isn't divisible by p. He guarantees you that under these conditions such t always exists. If there are several such t, output any of them.
As the input is quite large, please use fast input reading methods.
Input
The first line of the input contains three integers, n, m and p (1≤n,m≤106,2≤p≤109), — n and m are the number of terms in f(x) and g(x) respectively (one more than the degrees of the respective polynomials) and p is the given prime number.
It is guaranteed that p is prime.
The second line contains n integers a0,a1,…,an−1 (1≤ai≤109) — ai is the coefficient of xi in f(x).
The third line contains m integers b0,b1,…,bm−1 (1≤bi≤109) — bi is the coefficient of xi in g(x).
Output
Print a single integer t (0≤t≤n+m−2) — the appropriate power of x in h(x) whose coefficient isn't divisible by the given prime p. If there are multiple powers of x that satisfy the condition, print any.
Examples
input
3 2 2
1 1 2
2 1
output
1
input
2 2 999999937
2 1
3 1
output
2
Note
In the first test case, f(x) is 2x2+x+1 and g(x) is x+2, their product h(x) being 2x3+5x2+3x+2, so the answer can be 1 or 2 as both 3 and 5 aren't divisible by 2.
In the second test case, f(x) is x+2 and g(x) is x+3, their product h(x) being x2+5x+6, so the answer can be any of the powers as no coefficient is divisible by the given prime.
思路: 给出两个本原多项式的系数,求两个多项式相乘之后,系数不可被质数p整除的项的指数。
由于p是质数,a%p!=0,b%p!=0,可得:a×b%p!=0
假设\(a_i\)是第一多项式中0~i第一个不可被p整除的数,\(b_j\)是第二多项式中0~j第一个不可被p整除的数,\(a_i×b_j\)的指数是\(i+j,i+j\)的系数之和是\(a_0×b\)i+j\(+..+a_i×b_j+...+a\)i+j\(×b_0\)由于除了\(a_i×b_j\)其他项都包含能被p整除的因子,所以其他项之和能被整除,加上\(a_i×b_j\)不能整除了。
#include<iostream>
#include<string.h>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
#include<set>
#include<map>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
int main(){
int n,m,p;
scanf("%d%d%d",&n,&m,&p);
int a=-1,b=-1;
for(int i=0,x;i<n;++i){
scanf("%d",&x);
if(x%p!=0&&a==-1) a=i;
}
for(int i=0,x;i<m;++i){
scanf("%d",&x);
if(x%p!=0&&b==-1) b=i;
}
cout<<a+b<<endl;
return 0;
}
D. Nash Matrix
Nash designed an interesting yet simple board game where a player is simply required to follow instructions written on the cell where the player currently stands.
This board game is played on the n×n board. Rows and columns of this board are numbered from 1 to n. The cell on the intersection of the r-th row and c-th column is denoted by (r,c).
Some cells on the board are called blocked zones. On each cell of the board, there is written one of the following 5 characters — U, D, L, R or X — instructions for the player. Suppose that the current cell is (r,c). If the character is R, the player should move to the right cell (r,c+1), for L the player should move to the left cell (r,c−1), for U the player should move to the top cell (r−1,c), for D the player should move to the bottom cell (r+1,c). Finally, if the character in the cell is X, then this cell is the blocked zone. The player should remain in this cell (the game for him isn't very interesting from now on).
It is guaranteed that the characters are written in a way that the player will never have to step outside of the board, no matter at which cell he starts.
As a player starts from a cell, he moves according to the character in the current cell. The player keeps moving until he lands in a blocked zone. It is also possible that the player will keep moving infinitely long.
For every of the n2 cells of the board Alice, your friend, wants to know, how will the game go, if the player starts in this cell. For each starting cell of the board, she writes down the cell that the player stops at, or that the player never stops at all. She gives you the information she has written: for each cell (r,c) she wrote:
a pair (x,y), meaning if a player had started at (r,c), he would end up at cell (x,y).
or a pair (−1,−1), meaning if a player had started at (r,c), he would keep moving infinitely long and would never enter the blocked zone.
It might be possible that Alice is trying to fool you and there's no possible grid that satisfies all the constraints Alice gave you. For the given information Alice provided you, you are required to decipher a possible board, or to determine that such a board doesn't exist. If there exist several different boards that satisfy the provided information, you can find any of them.
Input
The first line of the input contains a single integer n (1≤n≤103) — the side of the board.
The i-th of the next n lines of the input contains 2n integers x1,y1,x2,y2,…,xn,yn, where (xj,yj) (1≤xj≤n,1≤yj≤n, or (xj,yj)=(−1,−1)) is the pair written by Alice for the cell (i,j).
Output
If there doesn't exist a board satisfying the information that Alice gave you, print a single line containing INVALID.
Otherwise, in the first line print VALID. In the i-th of the next n lines, print the string of n characters, corresponding to the characters in the i-th row of the suitable board you found. Each character of a string can either be U, D, L, R or X. If there exist several different boards that satisfy the provided information, you can find any of them.
Examples
input
2
1 1 1 1
2 2 2 2
output
VALID
XL
RX
input
3
-1 -1 -1 -1 -1 -1
-1 -1 2 2 -1 -1
-1 -1 -1 -1 -1 -1
output
VALID
RRD
UXD
ULL
思路: 有终点的位置和没有终点的位置互不相关,可以分别构造。
对于(-1 -1)没有终点的点。可以考虑让任意两个相邻的(-1 -1)相互到达,对于没有多余的点,可以让它到达相邻的其他两个互相到达的点。如果X点没有相邻的X则无解
对于自己是自己终点的点,就是X,然后类似并查集连通块的操作,让终点是它且相邻的点往它这走。
最后在遍历一遍是否有没有标记上的点,如果有就是无解。
#include<iostream>
#include<string.h>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
#include<set>
#include<map>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=1010;
PII pg[N][N];
char cg[N][N];
bool vis[N][N];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int n;
char dir[]={'L','R','D','U'};
bool dfs(int x,int y){
for(int i=0;i<4;++i){
int xx=dx[i]+x,yy=dy[i]+y,t=pg[xx][yy].first;
if(xx<0||xx>n||yy<0||yy>n) continue;
if(t==-1){
if(cg[xx][yy]==dir[i]){
cg[x][y]=dir[i^1];
return true;
}
}
}
for(int i=0;i<4;++i){
int xx=dx[i]+x,yy=dy[i]+y,t=pg[xx][yy].first;
if(t==-1){
cg[x][y]=dir[i^1];
return true;
}
}
return false;
}
void dfs2(int x,int y,int i,int j){
vis[x][y]=true;
for(int k=0;k<4;++k){
int xx=dx[k]+x,yy=dy[k]+y;
if(xx<0||xx>n||yy<0||yy>n||vis[xx][yy]==true) continue;
if(pg[xx][yy].first==i&&pg[xx][yy].second==j){
char c;
cg[xx][yy]=dir[k];
dfs2(xx,yy,i,j);
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
scanf("%d%d",&pg[i][j].first,&pg[i][j].second);
if(pg[i][j].first==i&&pg[i][j].second==j){
cg[i][j]='X';
}
}
}
bool f=0;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(pg[i][j].first==-1){
if(!dfs(i,j)) {
f=1;
break;
}
}
}
if(f) break;
}
if(f){
puts("INVALID");
return 0;
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(cg[i][j]=='X'){
dfs2(i,j,i,j);
}
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
char ch=cg[i][j];
if(ch!='X'&&ch!='L'&&ch!='R'&&ch!='U'&&ch!='D') {
f=1;
break;
}
}
if(f) break;
}
if(f){
puts("INVALID");
return 0;
}
puts("VALID");
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
cout<<cg[i][j];
}
cout<<endl;
}
return 0;
}