地址(需内网):http://acm.hit.edu.cn/contest/141
第一次正式的打这类比赛,总体来说还是比较菜。
总共A了四道题,Ranking NO.25,Penalty 17:41:57,First Blood 1。
简谈下此次比赛吧。
A题
水题,字符串处理,读题有坑。WA了9发。
大致题意;定义一个q-string,重点长度大于1,按照step1删去末尾e,step2将辅音字母后的y改成i,加上er。
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
| #include <bits/stdc++.h>
using namespace std; int main() { int t; scanf("%d",&t); int cas=0; while(t--) { char s[10086]; scanf("%s",s); int len=strlen(s); int k=len-1; if(s[k]!='e'&&s[k]!='y') { printf("Case #%d: %ser\n",++cas,s); continue; } else { while(s[k]=='e'&&k>=0) { s[k]='\0'; k--; } } if(k==-1) printf("Case #%d: eer\n",++cas); else if(k<=1) printf("Case #%d: %ser\n",++cas,s); else { if(s[k]!='y') printf("Case #%d: %ser\n",++cas,s); else if(s[k-1]!='a'&&s[k-1]!='e'&&s[k-1]!='i'&&s[k-1]!='o'&&s[k-1]!='u') { s[k]='i'; printf("Case #%d: %ser\n",++cas,s); } else printf("Case #%d: %ser\n",++cas,s); } } return 0; }
|
B题
题意:数字黑洞,除了四位数字相同的(包括0)四位数(不足的补0),四个数字降序和升序组成新四位数相减,最终会在6174无限循环。求计算过程。
思路:转换成字符串处理。(没注意数据范围被坑了几次)
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
| #include <bits/stdc++.h>
using namespace std;
int cmp(int a,int b) { return a>b; }
int ce[4],de[4]; char a[4];
void div(char mmp[]) { de[0]=mmp[0]-'0'; de[1]=mmp[1]-'0'; de[2]=mmp[2]-'0'; de[3]=mmp[3]-'0'; for(int i=0;i<4;i++){ ce[i]=de[i]; } sort(ce,ce+4); sort(de,de+4,cmp); }
int main() { int t; scanf("%d",&t); int cas=0; while(t--) { int num; scanf("%d",&num); printf("Case #%d:\n",++cas); if(num==0){ printf("0000 - 0000 = 0000\n"); continue; } for(int i=0;i<4;i++){ a[i]=(num%10)+'0'; num/=10; } a[4]='\0'; char idx=a[0]; if(idx==a[1]&&idx==a[2]&&idx==a[3]) { printf("%s - %s = 0000\n",a,a); continue; } int flag=-1; while(1) { div(a); int fr=de[0]*1000+de[1]*100+de[2]*10+de[3]; int la=ce[0]*1000+ce[1]*100+ce[2]*10+ce[3]; int tmp=fr-la; if(tmp==6174) flag=1; if(tmp==6174&&flag==1) flag=2; for(int i=0;i<4;i++){ a[i]=(tmp%10)+'0'; tmp/=10; } printf("%d%d%d%d - %d%d%d%d = %04d\n",de[0],de[1],de[2],de[3],ce[0],ce[1],ce[2],ce[3],fr-la); if(flag==2) break; } } return 0; }
|
C题
简单贪心,每次取最小的两个数相加即可。
数据范围较大n<=100000
错误思路:快排,每次快排的效率是O(n2 logn),铁定超时系列。
正确做法:堆,用优先队列即可实现。
暴力做法:据观察,每个数不超过1000,十万个数相加不超过1亿,故可以采取计数排序的思想,暴力扫。
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 <bits/stdc++.h>
using namespace std;
int a[100000000];
int main() { int n; while(scanf("%d",&n)&&n) { int ans=0; memset(a,0,sizeof(a)); for(int i=0; i<n; i++) { int x; scanf("%d",&x); a[x]++; } int cnt=n; int i=0; int tmp=-1; while(cnt!=1) { if(a[i]==0) { i++; continue; } if(a[i]==1&&tmp==-1) { tmp=i; a[i]--; continue; } if(a[i]==1&&tmp!=-1) { ans+=tmp+i; a[i+tmp]++; tmp=-1; cnt--; a[i]--; if(cnt==1) break; else continue; } if(a[i]>=2&&tmp==-1) { a[2*i]++; a[i]-=2; ans+=2*i; cnt--; if(cnt==1) break; else continue; } if(a[i]>=2&&tmp!=-1) { a[i+tmp]++; ans+=i+tmp; a[i]--; cnt--; tmp=-1; if(cnt==1) break; } } printf("%d\n",ans); } return 0; }
|
K题
其实这题是没看懂的,莫名其妙拿了一血。
题意:给定一个序列,求一个序列,其中任意两个数的最大公因数大于1,计算其最大长度。
做法1:由于数据是随机生成的,奇偶各一半,直接计算偶数个数即可。
(我采用的这种做法,水数据2333)
正解:计算2-sqrt(maxnum)之间所有素数的倍数,取其最大值。
AC代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <bits/stdc++.h>
using namespace std; int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int a[n]; for(int i=0;i<n;i++) scanf("%d",&a[i]); int cnt=0; for(int i=0;i<n;i++){ if(a[i]==2)cnt++; else if(a[i]%2==0)cnt++; } printf("%d\n",cnt); } return 0; }
|