华东交通大学2014年ACM“双基”程序设计竞赛解题报告
来源:互联网 发布:淘宝犯法 编辑:程序博客网 时间:2024/04/27 19:55
1001 KK的GFriend
本题水题。遍历输入数据给出的字符串。如果出现的I LOVE U各个字符都至少都有m个的话,则满足要求,否则不满足。
之前比赛时,输出描述的字符串和Sample Output不符(Sample Output为正确答案),导致部分同学wrong answer,请见谅。
#include<iostream>#include<cstring>#include<string>#include<cstdio>using namespace std;const int maxn=10001;char inp[maxn];int num[6];int main(){ int cas,n,m; scanf("%d",&cas); while(cas--) { memset(num,0,sizeof(num)); scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%s",&inp); for(int i=0; i<strlen(inp); i++) { switch(inp[i]) { case 'I':num[0]++;break; case 'L':num[1]++;break; case 'O':num[2]++;break; case 'V':num[3]++;break; case 'E':num[4]++;break; case 'U':num[5]++;break; } } } int res=maxn; for(int i=0; i<6; i++) res=min(res,num[i]); if(res>=m) printf("KK will have a girlfriend!\n"); else printf("KK can only have gay friend~\n"); } return 0;}
1002 炮打学弟
这题是一道简单题,主要是要考虑的情况稍多,如果都考虑到了就没有什么了。
需要注意的地方:
1. x2<x1 输出 Xue di so diao can fly
2. x2=x1时
(1)y=0 输出0.00
(2)y!=0&&vx>0 输出 Xue di so diao can fly
3. x2>x1&&vx=0输出 Xue di so diao can fly
其他情况常规的算一下就可以了。
标准程序:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<vector>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<stdlib.h>#include<time.h>using namespace std;#define mmax 100000+100int main(){ int x1,x2,y,vx; double vy,g=9.8; int t; cin>>t; //freopen("I:\\input.txt","r",stdin); //freopen("I:\\ouput.txt","w",stdout); while(t--){ cin>>x1>>x2>>y>>vx; if(x1>x2){ cout<<"Xue di so diao can fly"<<endl; continue; } if(x1==x2){ if(y==0){ printf("%.2f\n",0.00); continue; } else if(vx>0) cout<<"Xue di so diao can fly"<<endl; else{ double t=sqrt(2*y/g); printf("%.2f\n",g*t); } continue; } else{ if(vx==0){ cout<<"Xue di so diao can fly"<<endl; continue; } else{ double t=(x2-x1)*1.0/vx; vy=(0.5*g*t*t+y)/t; printf("%.2f\n",vy); } } }}
1003 区间平均值
这题是水题,直接暴力求平均值即可。
1004 饿了么
这题是水题,直接排个序就好了,1000的数据量,用冒泡排序都可以。
1005 分辨机器人
m<=15 2^15==32768 所以可以直接暴力解决。但是由于开始数据出问题了,导致很多同学wa了,实在抱歉,想知道自己算法是否OK的同学可以到赛后(http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1005&cid=25698&problem=Problem%20%20E)提交。
标准程序:
#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <queue>#include <cmath>#include <vector>#include <set>#include <bitset>#include <map>#define pb push_back#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long LL;using namespace std;int s[105][20];int T,n,m,ans;int B[20];string ko;map<string,int>M;void dfs(int *B,int num){ if(num==m) { M.clear(); for(int i=1;i<=n;i++) { ko = ""; for(int j=1;j<=m;j++) if(B[j]==1) ko += (s[i][j]+'0'); if(M[ko]) return ; else M[ko] = 1; } int flag = 0; for(int i=1;i<=m;i++) flag+=B[i]; if(ans>flag) ans = flag; } else { B[num+1] = 0; dfs(B,num+1); B[num+1] = 1; dfs(B,num+1); }}void solve(){ ans = m; B[0] = 0; dfs(B,0); printf("%d\n",ans);}int main(){ scanf("%d",&T); while(T--) { memset(B,0,sizeof(B)); scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) { scanf("%d",&s[i][j]); } solve(); } return 0;}
1006 佳米的问题
这是一个想法题,首先我们需要找出最大的LCM(x,y).由于x+y==m&& x>=1 && y>=1 ,有一个很简单的数学依据,加入我们只是找(x*y)最大,那肯定( m/2*(m-m/2) )最大,因为这就是一个开口向下的二次函数曲线,而顶点就是(m/2)或者(m-m/2),但是我们要找的是x与y的最小公倍数,所以只需要从m/2开始向下枚举x,找到gcd(x,m-x)==1,此时LCM(x,y)最大。
然后就是如何用LCM(x,y)去填充数组使得最小的元素最大的问题了,那么这个其实有一个很简单的方法,直接二分答案即可。
标准程序:
#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <queue>#include <cmath>#include <vector>#include <set>#include <bitset>#include <map>#define pb push_back#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long LL;using namespace std;LL gcd(LL a,LL b){ return a==0?b:gcd(b%a,a);}const int maxn = 100010;LL s[maxn];LL T,n,num,m;bool solve(LL mid,LL num){ LL ok = num; for(int i=1;i<=n;i++) { if(s[i] < mid){ ok -= abs( mid - s[i] ); } if(ok<0) break; } return ok>=0;}int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out2.txt","w",stdout); #endif ///ONLINE_JUDGE scanf("%I64d",&T); while(T--){ scanf("%I64d",&n); for(int i=1;i<=n;i++) { scanf("%I64d",&s[i]); } scanf("%I64d",&m); for(LL i=m/2;i>=1;i--) { if(gcd(i,m-i)==1) { num=i*(m-i); break; } } LL l=-1*1e9,r = 1ll*1e16,mid,ans=-1*1e9; while(l<=r) { mid = (l+r)/2; if(solve(mid,num)){ ans = max(ans,mid); l = mid + 1; } else r = mid - 1; } printf("%I64d\n",ans); } return 0;}
1007 Crisis
图论。本题可谓是排在难题位置的简单题。描述偏多,但是只要学习过最大流算法的同学应该都可以做出来。
N件武器,每件都可以选择特定的几个目标进行攻击。但是每件武器只允许攻击一次并只能造成1点伤害。因此,我们构建网络,将n件武器每件当作一个点,与源点相连,形成的边容量为1。再将m个目标当作n个点,若某一武器能够攻击到敌人,则将它们两个点相连,边容量为1。
又由于每个敌人的护盾有限。而被摧毁的战舰无法再被攻击,因此,将m个敌人分别与汇点相连,边容量为该敌人的护盾值。
至此,建模完毕。接下来只需要套用最大流算法,即可计算出最大攻击输出。
标准程序:#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>#define INF 0x7fffffffusing namespace std;const int maxn=1010;class Edge{public : int from,to,cap,flow; Edge(int fr,int t,int c,int fl) { from=fr; to=t; cap=c; flow=fl; };};class Dinic{private: int s,t,c,m,n; vector<Edge>edges; vector<int>G[maxn]; bool vis[maxn]; int dist[maxn]; int cur[maxn];public: void AddEdge(int from,int to,int cap) { Edge e(from,to,cap,0); edges.push_back(e); e.from=to; e.to=from; e.cap=0; edges.push_back(e); c=edges.size(); G[from].push_back(c-2); G[to].push_back(c-1); } bool BFS() { queue<int>Q; memset(vis,0,sizeof(vis)); Q.push(s); dist[s]=0; vis[s]=1; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i<G[x].size(); i++) { Edge& e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow) { vis[e.to]=1; dist[e.to]=dist[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x,int a) { if(x==t||a==0)return a; int flow=0,f; for(int& i=cur[x]; i<G[x].size(); i++) { Edge& e=edges[G[x][i]]; if(dist[x]+1==dist[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } int Maxflow(int s,int t) { this->s=s; this->t=t; int flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow+=DFS(s,INF); } return flow; } void init() { edges.clear(); for(int i=0; i<maxn; i++) { G[i].clear(); dist[i]=0; } }} Do;int main(){ int n,m,k,hp,t; cin>>t; while(t--) { cin>>n>>m; Do.init(); for(int i=1; i<=n; i++) { Do.AddEdge(0,i,1); cin>>k; int tar; for(int j=1; j<=k; j++) { cin>>tar; Do.AddEdge(i,n+tar,1); } } for(int i=1; i<=m; i++) { cin>>hp; Do.AddEdge(n+i,n+m+1,hp); } cout<<Do.Maxflow(0,n+m+1)<<endl; } return 0;}
1008 KiKi的难题
这题是一个简单的三维的dp。
Intdp[110][110][110];
dp[i][j][k] 表示第i个岛屿到第j个岛屿没有挖且使用魔法棒剩余次数为k 所能获得大最大价值
for(int i=n-1; i>=1; i--)//枚举剩余岛屿的个数for(int j=1;j+i-1<=n; j++)//枚举最左边的岛屿位置for(int k=0; k<=m; k++)//枚举魔法棒可使用的次数{ int add=j+i-1; if(j!=1) { dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k]+p[j-1]); dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k+1]+(m-k)*p[j-1]); } if(add!=n) { dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k]+p[add+1]); dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k+1]+(m-k)*p[add+1]); }}
最后输出最大值就可以了。
标准程序:#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<vector>#include<cstdlib>#include<stack>#include<queue>#include<map>#include<algorithm>using namespace std;int dp[110][110][110];int main(){ int t;cin>>t; int n,m,p[110]; while(t--){ cin>>n>>m; for(int i=1;i<=n;i++) cin>>p[i]; memset(dp,0,sizeof(dp)); for(int i=n-1; i>=1; i--) { for(int j=1; j+i-1<=n; j++) for(int k=0; k<=m; k++) { int add=j+i-1; if(j!=1) { dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k]+p[j-1]); dp[j][add][k]=max(dp[j][add][k],dp[j-1][add][k+1]+(m-k)*p[j-1]); } if(add!=n) { dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k]+p[add+1]); dp[j][add][k]=max(dp[j][add][k],dp[j][add+1][k+1]+(m-k)*p[add+1]); } } } int mmax=0; if(m==0) cout<<dp[1][1][0]+p[1]<<endl; else{ for(int i=1;i<=n;i++) mmax=max(mmax,dp[i][i][1]+p[i]*m); cout<<mmax<<endl; } } return 0;}
以上即是本次比赛的全部解题报告以及部分标准程序代码,感谢大家对我校比赛的支持!
- 华东交通大学2014年ACM“双基”程序设计竞赛解题报告
- 华东交通大学2014年ACM“双基”程序设计竞赛解题报告
- 华东交通大学2013年ACM“双基”程序设计竞赛 解题报告
- 华东交通大学2014年ACM“双基”程序设计竞赛部分解题报告
- 华东交通大学2013ACM“双基”程序设计竞赛 解题报告
- 华东交通大学2013年ACM“双基”程序设计竞赛获奖公示
- 华东交通大学2013年ACM“双基”程序设计竞赛
- 华东交通大学2015年ACM“双基”程序设计竞赛
- 华东交通大学2016年ACM“双基”程序设计竞赛
- 华东交通大学2014年ACM“双基”程序设计竞赛(部分水题)
- 华东交通大学2016年ACM“双基”程序设计竞赛 A:简单题
- 华东交通大学2016年ACM“双基”程序设计竞赛 H:毛线数列最值
- 2014年山东省第五届ACM大学生程序设计竞赛解题报告
- 河南省第七届ACM大学生程序设计竞赛 解题报告
- 第七届北京交通大学ACM程序设计竞赛网络预赛一
- 第七届北京交通大学ACM程序设计竞赛网络预赛二
- 2014嘉杰信息杯ACM/ICPC湖南程序设计邀请赛暨第六届湘潭市程序设计竞赛 解题报告
- 《阿里巴巴集团杯》2011(春)HIT ACM程序设计竞赛 解题报告
- 函数inet_addr和inet_ntoa
- poj2528离散化+线段树
- 一套完善的Android异步任务类
- 关于错误"IE无法打开Inte站点************。已终止操作"
- 管海兵-云计算可用性问题
- 华东交通大学2014年ACM“双基”程序设计竞赛解题报告
- Observer模式
- PAT 1089. Insert or Merge (25)
- 利用shell脚本遍历某个目录下的所有文件
- 常用浏览器模拟移动端方法
- jsp中img标签路径不能包含中文,关于Tomcat的URIEncoding以及GET乱码
- ios多设备多分辨率适配
- outlook 过滤再接着处理如转发,移动到文件夹,删除等
- 生存函数