FOJ-2011年11月月赛
来源:互联网 发布:oppo软件删不掉怎么办 编辑:程序博客网 时间:2024/06/05 18:01
学长给开题做的,随机队员时运气不好,把自己队的随走了一个,就剩zcy和我两个人打的。开局还行,但是毕竟人少,没法很快连续出题,后来出题速度就慢了。
A:
FZU 2054
水题,判断最大值在哪边,输出。
#include<cstdio>#include<algorithm>using namespace std;const int inf=0x3f3f3f3f;const int maxn=10010;int main(){ int t; scanf("%d",&t); while(t--){ int t1,t2; int a,b,c; scanf("%d%d%d",&a,&b,&c); t1=max(a,b),t1=max(t1,c); scanf("%d%d%d",&a,&b,&c); t2=max(a,b),t2=max(t2,c); printf("%d\n",t1>t2?1:2); } return 0;}
B:
FZU 2055
一开始我敲,敲了一半发现错了,后来zcy敲的。发现自己之前想麻烦了,数据量少,直接暴力就行。
#include<iostream>#include<string>using namespace std;string s[108],p,t;int n,op;bool path(string p,string d){ int len=p.length(); if(len>=d.length()) return false; for(int i=0;i<len;++i){ if(p[i]!=d[i]) return false; } return true;}bool duc(string t,string d){ int lt=t.length(),ld=d.length(); if(lt>ld) return false; for(int i=lt-1,j=ld-1;i>=0;--i,--j){ if(t[i]!=d[j]) return false; } return true;}void judge(string p,string t){ for(int i=0;i<n;++i) if(path(p,s[i])&&duc(t,s[i])) cout << s[i] <<endl; return ;}int main(){ ios::sync_with_stdio(false); int T; cin >> T; while(T--){ cin >> n >> op; for(int i=0;i<n;++i) cin >> s[i]; for(int i=0;i<op;++i){ cin >> p >> t; judge(p,t); } } return 0;}
C:
FZU 2056
比赛时没想到,赛后问了学长思路,DP所有矩形的面积,二分搜索最大边长。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=1010;int n,m,lim;int d[maxn][maxn];bool ok(int h){ for(int i=h;i<=n;++i) for(int j=h;j<=m;++j) if(d[i][j]-d[i-h][j]-d[i][j-h]+d[i-h][j-h]<=lim) return true; return false;}int main(){ int t;scanf("%d",&t); while(t--){ memset(d,0,sizeof(d)); scanf("%d%d%d",&n,&m,&lim); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ int k; scanf("%d",&k); d[i][j]=d[i-1][j]+d[i][j-1]-d[i-1][j-1]+k; } int top=min(n,m),bott=0,best=0; while(bott<=top){ int mid=(top-bott)/2+bott; if(ok(mid)) best=max(best,mid*mid),bott=mid+1; else top=mid-1; } printf("%d\n",best); } return 0;}
D:
比赛时看成是1w*1w的数据量,要写类似并查集的树。赛后补题时发现是1w * 100。
记录每个人的性别和孩子编号。然后查询就好。
#include<cstdio>#include<cstring>using namespace std;const int maxn=10010;int ch[maxn],len;bool sex[maxn];char ans[maxn];bool f(int k,int x,int y){ len=0; while(ch[y]){ ans[len++]=sex[y]?'M':'F'; if(x==(y=ch[y])){ printf("%d ",k); for(int i=len-1;i>=0;--i) putchar(ans[i]); puts(""); return true; } } return false;}int main(){ int t;scanf("%d",&t); while(t--){ memset(ch,0,sizeof(ch)); memset(sex,0,sizeof(sex)); int n;scanf("%d",&n); int num=n/2; for(int i=0;i<num;++i){ int cur,f,m; scanf("%d%d%d",&cur,&f,&m); ch[f]=ch[m]=cur,sex[m]=true; } int q;scanf("%d",&q); while(q--){ int x,y; scanf("%d%d",&x,&y); if(!f(1,x,y)&&!f(0,y,x)) printf("Relative\n"); } } return 0;}
E:
FZU 2058
比赛时用STL写的O(nlogn)算法超时,最后没改数组写。
赛后得知可以用O(n)算法,所以赛后补了这道。两个指针从前后分别遍历数组,满足条件时统计个数。
#include<cstdio>#include<algorithm>using namespace std;typedef long long LL;const int maxn=100010;int a[maxn];int Scan(){ int res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res;}int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ getchar(); for(int i=0;i<n;++i) a[i]=Scan(); sort(a,a+n); LL ans=0; int l=0,r=n-1; while(l<=r){ if(a[l]==a[r]){ if(a[l]+a[r]==m) ans+=LL(r-l)*(r-l+1)/2; break; } if(a[l]+a[r]==m){ int ll=l,rr=r; while(a[l]==a[ll]) ++l; while(a[r]==a[rr]) --r; ans+=LL(l-ll)*(rr-r); } else if(a[l]+a[r]>m) --r; else ++l; } printf("%I64d\n",ans); } return 0;}
H:
FZU 2061
比赛时准备找规律过掉这道题,快结束了得知找钱可以找好几张,之前推的不对。看也来不及推了,就和zj交流经验,再后来zcy按照zj说的过掉了这道题。。
打3^0~3^n和的表。对每个输入遍历计数,输出。
#include<stdio.h>#include<math.h>int main(){ int num[36]; num[0]=1; for(int i=1;i<20;++i) num[i]=num[i-1]+pow(3,i); int n; while(~scanf("%d",&n)){ int ans=1; for(int i=0;i<20;++i){ if(n>num[i]) ++ans; else break; } printf("%d\n",ans); } return 0;}
I:
FZU 2062
开场我翻题时看到题目配图说是水题,就跟zcy说了,我提出思路,他感觉正确,就打了交过了。
一开始思路不太对,导致最后代码很挫。
#include<cstdio>using namespace std;const int inf=0x3f3f3f3f;const int maxn=10010;int d(int k){ if(k==1) return 1; return d(k>>1)+1;}int main(){ int n; while(~scanf("%d",&n)) printf("%d\n",d(n)); return 0;}
J:
FZU 1859
zcy读到说是个画图的水题,我写出来,一块Debug之后过的。
对每个图分四份递归,然后输出就好。
#include<cstdio>#include<cstring>using namespace std;const int inf=0x3f3f3f3f;const int maxn=1030;char g[maxn][maxn];void draw(int n,int l1,int l2,int r1,int r2){ if(n==1){g[l1][r1]='@';return;} int k=1<<(n-2); draw(n-1,l1,l1+k,r1,r1+k); draw(n-1,l2-k,l2,r1,r1+k); draw(n-1,l2-k,l2,r2-k,r2); return;}int main(){ int n; while(~scanf("%d",&n)&&n){ memset(g,' ',sizeof(g)); draw(n,0,1<<(n-1),0,1<<(n-1)); int k=1<<(n-1); for(int i=0;i<k;++i){ for(int j=k-1;j>=0;--j) if(g[i][j]=='@') {g[i][j+1]=0;break;} puts(g[i]); } puts(""); } return 0;}
K:
比赛时以为是用线段树做,所以敲了线段树,用书上模板坑了好久。赛后学长说可以DP求,补了一个用DP过的。
n=1000,m=100000。
线段树的建树复杂度O(nlogn),查询复杂度O(mlogn),总复杂度O(mlogn)。
DP处理数据复杂度O(n^2),查询复杂度O(1),总复杂度O(n^2)。
还是DP更快一些。
更重要的是,个人感觉DP好写,写线段树容易出错。
//DP版:#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=1010;int d[maxn][maxn];int main(){ int tt=0,n; while(~scanf("%d",&n)){ memset(d,0,sizeof(d)); for(int i=1;i<=n;++i) scanf("%d",&d[i][i]); for(int i=1;i<=n;++i){ for(int j=i+1;j<=n;++j) d[i][j]=max(d[i][j-1],d[j][j]); } int q;scanf("%d",&q); printf("Case #%d:\n",++tt); while(q--){ int l,r;scanf("%d%d",&l,&r); printf("%d\n",l<=r?d[l][r]:max(d[1][r],d[l][n])); } puts(""); } return 0;}
//线段树版:#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf=0x3f3f3f3f;const int maxn=1010;int cnt,n,d[(1<<12)-1];void init(int n_){ cnt=0,n=1; while(n<n_) n<<=1,++cnt; memset(d,-1,sizeof(d));}int q(int a,int b,int k,int l,int r){ if(r<=a||b<=l) return -1; if(a<=l&&r<=b) return d[k+1]; return max(q(a,b,2*k+1,l,(l+r)/2),q(a,b,2*k+2,(l+r)/2,r));}int main(){ int tt=0; while(~scanf("%d",&n)){ int tmp=n; init(n); for(int i=1<<cnt;i<(1<<cnt)+tmp;++i) scanf("%d",&d[i]); int t=cnt-1; while(t>=0){ int num=1<<(cnt-t); for(int i=1<<t;i<1<<(t+1);++i) d[i]=max(d[i*2],d[i*2+1]); --t; } int m; scanf("%d",&m); printf("Case #%d:\n",++tt); for(int i=0;i<m;++i){ int l,r; scanf("%d%d",&l,&r); --l,--r; int ans=-1; if(l>r) ans=max(q(0,r+1,0,0,n),q(l,n,0,0,n)); else ans=q(l,r+1,0,0,n); printf("%d\n",ans); } printf("\n"); } return 0;}
写在后面:
开场我从前往后读,zcy从后往前读。
前面的中文,读得快,我看A水,直接打了交,A1y(3)。然后继续看B是模拟,不想写模拟,跳过。C不会,D以为要建树,跳过。
E~K是英文题,挨个点着看了一遍。看到I,图上说这是水题,我就读了一遍,跟zcy讲了题意。我们感觉可做,但因为是数学,准备先放一放,一会再做。继续读题。
读别的题时,灵光乍现,感觉是二分一类的做法,跟zcy说了一下,他感觉对。就敲了,一开始想成分奇偶讨论了,所以写成递归,后来发现只需要数位数就行。提交I1y(13)。
再后来,我敲B,zcy读题,读到J水,跟我说了。原本准备敲完B之后再弄,但是后来发现B敲错了。就开始做J,一块Debug之后过了,提交,交在E题上了,重交J1y(55)。至此打得还不错,三道都是1y,都是FB。
再往后就有点乱了,开始看E,用map写的,不过脑补复杂度O(nlogn),应该是STL差个常数。跳过,看其他题。
zcy给我讲K题意,我以为是线段树,我开始敲K。敲了好久样例不过。下机器,zcy敲B。Debug过程中,zcy在我的多次干扰下过掉了B,B1y(150)。
之后我继续上机改K,两次WA之后,K3y(168)。
再往后我们几乎没正经打了,尝试了使用hash_map/hash_set过E,CE,找CB头文件粘上,依然CE。后来的时间大部分都在猜H题解法,直到最后与其他队成员交流经验,莫名其妙的过掉了,中途CE两次,H3y(295)。
赛后问了学长其他几道题的做法,补了几道题。
- FOJ-2011年11月月赛
- FOJ 2014 4月月赛 D多米诺骨牌
- FZU 2011年11月月赛 F 2059 MM
- 洛谷11月月赛总结
- 【洛谷月赛】洛谷11月月赛·Day1
- 洛谷11月月赛·Day2-2015
- 洛谷11月月赛Round2订正
- [codeplus 11月月赛]T1 jogging
- [codeplus 11月月赛]T2 timber
- FZU2011年3月月赛小结
- nyist14年3月月赛题解
- NEU 2016年2月月赛总结
- bzoj4885: [Lydsy2017年5月月赛]长方体
- BZOJ4885: [Lydsy2017年5月月赛]长方体
- [Lydsy2017年4月月赛]抵制克苏恩
- [Lydsy2017年4月月赛]抵制克苏恩
- bzoj5049 [Lydsy2017年5月月赛]导航系统
- FOJ有奖月赛-2011年11月 E Another a+b
- 情报破译-Cryptanalysis
- STL运用的C++技术(3)——模板实参推断
- 媒体播放回顾
- java线程之synchronized的用法详解
- STL运用的C++技术(5)——重载操作符
- FOJ-2011年11月月赛
- Java5、Java6、Java7的新特性
- python3 列表
- STL运用的C++技术(6)——函数对象
- wordpress crop 截图 not working 没有生成 缩略图问题 安装 gd 库
- STL运用的C++技术(7)——代码整合
- 遍历 Best Time to Buy and Sell Stock III
- STL运用的C++技术——后记
- 药品包装盒厂家,药品包装铁盒,药品保健品铁盒生产厂家