NENU ACM 14级训练赛 2014-12-21(年度收官战)
来源:互联网 发布:单词记忆方法知乎 编辑:程序博客网 时间:2024/05/24 01:27
啥也不说了,直接看........题解。
A题:a+b
是个人就能过~
B题:排序
N就1000,你想咋排就咋排
#include<cstdio>#include<algorithm>using namespace std;const int M=1024;int a[M];int main(){ int t,n; while(~scanf("%d",&t)){ while(t--){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); } sort(a,a+n); for(int i=0;i<n;i++){ printf("%d%c",a[i],i==n-1?'\n':' '); } } } return 0;}
C题:二进制枚举
题目看着好像很厉害的样子,其实一看数据量,披萨上能放的东西的种类是16种。
对于披萨,这些东西就放或不放两种状态,总状态共2^16种,枚举这些状态,然后验证状态是否满足所有人的要求就可以了。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;#define M 10000struct request { int want; int dont;} req[M];int len=0;char result[M][100];int cnt=0;int input() { int j,want,dont; char str[100]= {0}; len=0; while(gets(str)) { want=0; dont=0; if(str[0]=='.') return 1; for(j=0; str[j]!= ';' ; j+=2) if(str[j]=='+') want|= (1<<(str[j+1]-'A')); else dont|= (1<<(str[j+1]-'A')); req[len].want = want; req[len].dont = dont; len++; } return 0;}int solve() { int state,j,i,x=0; char str[100]= {0}; for(state=0; state<(1<<16); state++) { for(j=0; j<len; j++) if( (state&req[j].want) || ( (~state)&req[j].dont) ) continue; else break; if(j==len) { strcpy(result[cnt], "Toppings: "); for(i=0; i<16; i++) if( state& (1<<i) ) str[x++] = 'A'+i; str[x]=0; strcat(result[cnt], str); cnt++; return 1; } } strcpy(result[cnt],"No pizza can satisfy these requests."); cnt++; return 0;}void output() { int i; for(i=0; i<cnt; i++) printf("%s\n",result[i]);}int main() { int res=0; while(1) { res = input(); if(!res) break; solve(); } output(); return 0;}
D题:BFS
vincent找的宽搜入门题,还是不错滴
#include<cstdio>#include<cstring>#include<queue>#define mt(a,b) memset(a,b,sizeof(a))using namespace std;const int M=1e5+10;bool vis[M];int n,k;struct Q{ int id,step;}now,pre;queue<Q> q;void solve(int x){ if(x<0||x>1e5||vis[x]) return ; vis[x]=true; now.id=x; now.step=pre.step+1; q.push(now);}int bfs(){ vis[n]=true; now.id=n; now.step=0; while(!q.empty()) q.pop(); q.push(now); while(!q.empty()){ pre=q.front(); q.pop(); if(pre.id==k) return pre.step; solve(pre.id+1); solve(pre.id-1); solve(pre.id*2); }}int main(){ while(~scanf("%d%d",&n,&k)){ mt(vis,0); printf("%d\n",bfs()); } return 0;}
E题:模拟
求给出的日期范围内素数月素数日的个数。
对于一般的日期模拟的题目,给一个笨笨的好方法,那就是一天一天的去模拟、去判断,因为一般日期范围都不会太大,写出的代码虽然丑,但是有保障,好调试。
本题就是这样,判断区间内每一天是否为素数月素数日。
注意闰年的影响。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int x[110]; int noleap[]= {0,0,9,11,0,11,0,11,0,0,0,10,0};//noLeap int leap[]= {0,0,10,11,0,11,0,11,0,0,0,10,0};//Leap int a1[]={0,31,29,31,30,31,30,31,31,30,31,30,31};//Leap int a2[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//noLeap bool isleap(int y){//判断是否为闰年 if((y%4==0&&y%100!=0)||y%400==0){ return true; } else return false; } void isprime(){//筛素数 memset(x,1,sizeof(x)); x[0]=0; x[1]=0; for(int i=2;i<=sqrt(100)+1;i++){ if(!x[i]) continue; for(int j=(i<<1);j<=100;j+=i){ x[j]=0; } } } int main(){ isprime(); int n,y1,m1,d1,y2,m2,d2; int ans; int i,j,k; while(~scanf("%d",&n)){ while(n--){ ans=0; scanf("%d%d%d%d%d%d",&y1,&m1,&d1,&y2,&m2,&d2); i=y1;//年 j=m1;//月 k=d1;//日 while(1){ if(i==y2&&j==m2&&k==d2) break; if(isleap(i)){ if(x[j]){ if(x[k]){ ans++; } } if(k==a1[j]){ j++; k=1; } else{ k++; } } else{ if(x[j]){ if(x[k]){ ans++; } } if(k==a2[j]){ j++; k=1; } else{ k++; } } if(j>12){ i++; j=1; k=1; } } if(x[m2]&&x[d2]) ans++;//判断最后一天 printf("%d\n",ans); } } return 0; }
F题:进制转换
求出a*b=c是哪个进制下的转换
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;int trans(int t,int b) { int k = 1; int ret = 0; while (t>0) { ret += (t%10)*k; t /= 10; k *= b; } return ret;}int main() { int Cas,minn,k,p,q,r; int a,b,c; scanf("%d",&Cas); while (Cas--) { scanf("%d%d%d",&p,&q,&r); a = p; b = q; c = r; minn = 0; while (a>0) { if (minn<a%10) minn = a%10; a /= 10; } while (b>0) { if (minn<b%10) minn = b%10; b /= 10; } while (c>0) { if (minn<c%10) minn = c%10; c /= 10; } int i; for (i=minn+1; i<=16; i++) { a = trans(p,i); b = trans(q,i); c = trans(r,i); if (a*b == c) break; } if (i == 17) i = 0; printf("%d\n",i); } return 0;}
G题:由于此题需要另一题的背景,不做,略过。
H题:高精度
#include<iostream>#include<string>#include<cmath>#include<cstring>#include<cstdio>using namespace std;const int M = 500;int a[M];int b[M];char s1[M],s2[M];int main() { int Cas,i,time=1; scanf("%d",&Cas); while(Cas--) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%s%s",s1,s2); int len1=strlen(s1); int len2=strlen(s2); for(i=len1-1; i>=0; i--) { a[len1-1-i]=(int)(s1[i]-'0'); } for(i=len2-1; i>=0; i--) { b[len2-1-i]=(int)(s2[i]-'0'); } int maxlen; if(len1>len2) maxlen = len1; else maxlen = len2; for(i=0; i<=maxlen+100; i++) { a[i]=a[i]+b[i]; while(a[i]>1) { a[i+1]++; a[i]-=2; } } for(i=maxlen+100; i>=0; i--) { if(a[i]) break; } printf("%d ",time); if(i==-1&&a[0]==0){ printf("0"); } else { for(; i>=0; i--) { printf("%d",a[i]); } } puts(""); time++; } return 0;}
I题:栈贪心模拟
给出城市的正视图,所有的大楼都是矩形,给出每个高度改变时的坐标,问最少可以看出有几个大楼。
可以看出,w和横坐标是没有用的。。。
用栈模拟,先将0压栈,然后遍历n个数,设当前高度为y,如果栈顶元素大于y的话,说明栈顶元素所代表的高度的楼找到了,就不断弹出栈顶元素并ans+1直到栈顶元素小于等于y,如果此时栈顶元素小于y的话,就将y压栈,否则continue。
#include<iostream> #include<cmath> #include<cstring> #include<stack> #include<cstdio> #define PI acos(-1.0) #define inf 0x3f3f3f3f #define E exp(double(1)) #define eps 1e-7 using namespace std; #ifdef __LL64 typedef __LL64 LL; #else typedef long long LL; #endif const int MAXN = 60000; int x,y[MAXN]; int main() { int n,w; while(~scanf("%d%d",&n,&w)) { for(int i=0; i<n; i++) { scanf("%d%d",&x,&y[i]); } y[n]=0; stack<int> st; int ans = 0; st.push(0); for(int i=0; i<=n; i++) { while(st.top()>y[i] && !st.empty()) { st.pop(); ans++; } if(y[i]!=st.top()) { st.push(y[i]); } } printf("%d\n",ans); } return 0; }
J题:二分
这是道被各种数据结构和算法碾压过的题,可以用二分、哈希、map、字典树这些玩意儿一一碾压过去。
这里讨论二分的做法,首先给字符串排个序,然后输入一个,就进行二分查找。
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;int k;struct Dictionary{ char s1[12]; char s2[12];}d[100100];bool cmp(Dictionary A,Dictionary B){ if(strcmp(A.s2,B.s2) == 1) return false; return true;}void binarySearch(char str[]){ int L = 0; int R = k-1; while(L<=R){ int mid = (L+R)>>1; if(!strcmp(d[mid].s2,str)){ puts(d[mid].s1); return; } if(~strcmp(d[mid].s2,str)) R = mid - 1; else L = mid + 1; } puts("eh"); return;}int main(){ k = 0; char tmp; while(1){ tmp = getchar(); if(tmp == '\n') break; d[k].s1[0] = tmp; scanf("%s%s",d[k].s1+1,d[k].s2); k++; tmp = getchar(); } sort(d,d+k,cmp);// for(int i=0;i<k;i++){// printf("%s---%s\n",d[i].s1,d[i].s2);// } char str[12]; while(~scanf("%s",str)){ binarySearch(str); } return 0;}
0 0
- NENU ACM 14级训练赛 2014-12-21(年度收官战)
- NENU ACM 13级训练赛 2014-12-21(四六级悔过战-_-|||)
- NENU ACM 13级训练赛 2014-12-06(福州大学第十一届程序设计竞赛)
- NENU ACM 13级训练赛 2014-11-29(Ural Regional School Programming Contest 2014)
- FJNU-14级MCS-ACM训练#2
- 2016级ACM寒假训练(一)
- 2016级ACM寒假训练(二)
- 2016级ACM寒假训练(三)
- 2016级ACM寒假训练(四)
- 2016级ACM寒假训练(五)
- 2016级ACM寒假训练(六)
- 2016级ACM寒假训练(七)
- 2016级ACM寒假训练(八)
- 9th NENU ACM-ICPC Contest Solving Report
- acm训练 2017 02 21
- acm训练推荐(1)
- acm训练推荐(2)
- acm训练推荐(3)
- va_start和va_end使用详解
- 探索Lua5.2内部实现:Garbage Collection(2)
- IOS键盘处理
- hadoop(八) - sqoop安装与使用
- linux下创建用户
- NENU ACM 14级训练赛 2014-12-21(年度收官战)
- linux创建 / 删除用户及用户管理
- cpu 如何合理地估算线程池大小?
- linux 添加用户、权限
- Linux添加/删除用户和用户组
- LeetCode:Integer to Roman
- 命名规范
- Mysql命令mysqldump:备份数据库
- UVA 621 Secret Research 水题模拟