2020 Multi-University Training Contest 3部分补题
1004 Tokitsukaze and Multiple
Tokitsukaze and Multiple
题意
有n个数字,相邻的两个数据可以合并相加,问在选择处理和不处理的条件下,存在最多有多少个p的倍数
思路
将x与相邻的相加并mod p,用map记录余数的出现,余数等于0即存在一个p的倍数,若一个非零余数第二次出现,说明在第一次与第二次相加时中间存在一个p的倍数,所以cnt++,并重置一些数据。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include<stdio.h> #include<algorithm> #include<iostream> #include<math.h> #include<string.h> #include<map> using namespace std; int main() { int t,n,p; int i,u,v; int cnt; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&p); map<int,int> m; cnt=0; m[0]=1; v=0; for(i=0;i<n;i++) { scanf("%d",&u); v=(v+u)%p; if(m[v]) { cnt++; m.clear(); v=0; m[0]=1; } else { m[v]=1; } } printf("%d\n",cnt); } return 0; }
|
1009 Parentheses Matching
Parentheses Matching
题意
将*替换成()或空字符,使括号的数量和配对平衡,若能达到则输出解决方案,
思路
首先数左括号的个数,并记录 * 的位置,如果碰到右括号,则左括号的个数抵消一,若最后左括号没有了,就去找在这个右括号前面是否存在 * ,存在的话就可以继续,否则无法继续匹配。在最后,如果左括号还是多了,那就从倒过来遍历去找 * 的位置,与之替代为右括号,直到左括号全部被抵消。在输出结果时,依然依据左括号的个数最后是否被抵消或者为负,如果左括号个数为正或负,则无法输出,反正输出字符串的非 * 项。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include<stdio.h> #include<string.h> char s[100010]; int to[100010]; void solve(int ls) { int cnt=0,i; for(i=1;i<=ls;i++) { if(s[i]=='(') cnt++; else if(s[i]==')') { cnt--; if(cnt<0) break; } } if(cnt==0) { for(i=1;i<=ls;i++) { if(s[i]!='*') printf("%c",s[i]); } printf("\n"); } else { printf("No solution!\n"); } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%s",s+1); int ls=strlen(s+1); int id=0,pre=0,cnt=0; for(int i=0;i<=ls;i++) to[i]=0; for(int i=1;i<=ls;i++) { if(s[i]=='(') cnt++; else if(s[i]==')') { cnt--; if(cnt<0) { if(to[id]==0) break; id=to[id]; s[id]='('; cnt=0; } } else to[pre]=i,pre=i; } if(cnt>0){ for(int i=ls;i>=1;i--){ if(s[i]=='*') s[i]=')',cnt--; if(cnt==0) break; } } solve(ls); } }
|