gdut校赛决赛题解
2016-04-21 12:38
274 查看
比较水的比赛,水下博客贴个题解。
Problem A: Krito的讨伐
直接模拟,把可见范围内的怪物都扔进优先队列,先杀防御低的,最后判断还有没有怪剩余就行了。
Problem B: Sward Art Online
我直接写了几个DP,貌似有菊苣枚举+DP,都是可以的。
Problem C: wintermelon的魔界寻路之旅
原题。
Problem D: 二叉树的中序遍历
超级简单题却被坑了,连续俩#就绝对是错的。
Problem E: 积木积水
水题
Problem F: 我是好人4
看队友的吧- -
http://chilumanxi.org/2016/04/21/gdut-2016-%E6%A0%A1%E8%B5%9Bf-%E6%88%91%E6%98%AF%E5%A5%BD%E4%BA%BA4/
Problem G: 我是水题
真是水题。。。
Problem A: Krito的讨伐
直接模拟,把可见范围内的怪物都扔进优先队列,先杀防御低的,最后判断还有没有怪剩余就行了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <vector> using namespace std; typedef struct Mon { int def; int add; int r; bool operator <(const Mon &r)const { return r.def<def; } } Mon; typedef struct { int num; vector<Mon>M; } room; priority_queue<Mon>que; int t; int n,m; long long int atk; bool dis[1005][1005]; room R[1005]; bool vis[1005]; bool flag=0; void add(int num) { vis[num]=1; if(R[num].num==0) { for(int i=0;i<n;i++) { if(dis[num][i] && vis[i]==0) add(i); } } else { for(int i=0;i<R[num].num;i++) que.push(R[num].M[i]); } } bool solve() { Mon tmp; add(0); while(!que.empty()) { tmp=que.top(); if(atk<tmp.def) { break; } que.pop(); atk+=tmp.add; R[tmp.r].num--; if(R[tmp.r].num==0) { for(int i=0;i<n;i++) { if(dis[tmp.r][i] && vis[i]==0) { add(i); } } } } long long int left=0; for(int i=0; i<n; i++) { left+=R[i].num; } if(left>0) return 0; return 1; } int main() { cin >> t; int a,b,c; Mon tmp; while(t--) { cin >> n >> m; while(!que.empty())que.pop(); memset(dis,0,sizeof(dis)); memset(R,0,sizeof(R)); memset(vis,0,sizeof(vis)); for(int i=0; i<n-1; i++) { scanf("%d%d",&a,&b); dis[a][b]=dis[b][a]=1; } cin >> atk; for(int i=0; i<m; i++) { scanf("%d%d%d",&a,&b,&c); R[a].num++; tmp.def=b,tmp.add=c; tmp.r=a; R[a].M.push_back(tmp); } if(solve()) cout << "Oh yes." << endl; else cout << "Good Good Study,Day Day Up." << endl; } return 0; }
Problem B: Sward Art Online
我直接写了几个DP,貌似有菊苣枚举+DP,都是可以的。
#include <iostream> #include <string> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> using namespace std; long long int t,m,a,b,c,d; long long int dp1[100005],dp2[100005],dp3[100005],dp4[100005]; long long int num[100005]; typedef struct { int atk,cost; }node; typedef struct { long long int atk,cost,num,buff; }newnode; node tou[100005]; newnode shou[100005]; node wuqi[100005]; node wuqi2[100005]; int main() { //freopen("input.txt","r",stdin); cin >> t; node temp; newnode temp1; long long int tmp,tmpa,tmpb,tmpc; while(t--) { memset(num,-1,sizeof(num)); cin >> m >> a >> b >> c >> d; for(long long int i=0;i<a;i++) { scanf("%lld%lld",&tmp,&tmpa); temp.cost=tmp; temp.atk=tmpa; tou[i]=temp; } for(long long int i=0;i<b;i++) { scanf("%lld%lld%lld%lld",&tmp,&tmpa,&tmpb,&tmpc); temp1.cost=tmp,temp1.atk=tmpa,temp1.num=tmpb,temp1.buff=tmpc; shou[i]=temp1; } for(long long int i=0;i<c;i++) { scanf("%lld%lld",&tmp,&tmpa); temp.cost=tmp; temp.atk=tmpa; wuqi[i]=temp; } for(long long int i=0;i<d;i++) { scanf("%lld%lld",&tmp,&tmpa); temp.cost=tmp; temp.atk=tmpa; wuqi2[i]=temp; } for(long long int i=0;i<a;i++) { temp=tou[i]; if(m-temp.cost<0) continue; if(dp1[m-temp.cost]<temp.atk) { dp1[m-temp.cost]=temp.atk; num[m-temp.cost]=i; } } memcpy(dp2,dp1,sizeof(dp1)); for(long long int i=0;i<b;i++) { temp1=shou[i]; for(long long int j=temp1.cost;j<=m;j++) { if(temp1.num!=-1 && temp1.num==num[j]) { if(dp2[j-temp1.cost]<dp1[j]+temp1.buff+temp1.atk) { dp2[j-temp1.cost]=dp1[j]+temp1.buff+temp1.atk; } } else { if(dp2[j-temp1.cost]<dp1[j]+temp1.atk) dp2[j-temp1.cost]=dp1[j]+temp1.atk; } } } memcpy(dp3,dp2,sizeof(dp2)); memset(num,-1,sizeof(num)); for(long long int i=0;i<c;i++) { temp=wuqi[i]; for(long long int j=temp.cost;j<=m;j++) { if(dp3[j-temp.cost]<dp2[j]+temp.atk) { dp3[j-temp.cost]=dp2[j]+temp.atk; num[j-temp.cost]=i; } } } memcpy(dp4,dp3,sizeof(dp3)); for(long long int i=0;i<c;i++) { temp=wuqi[i]; for(long long int j=temp.cost;j<=m;j++) { if(i==num[j]) continue; if(dp4[j-temp.cost]<dp3[j]+temp.atk) dp4[j-temp.cost]=dp3[j]+temp.atk; } } for(long long int i=0;i<d;i++) { temp=wuqi2[i]; for(long long int j=temp.cost;j<=m;j++) { if(dp4[j-temp.cost]<dp2[j]+temp.atk) dp4[j-temp.cost]=dp2[j]+temp.atk; } } long long int out=0; for(long long int i=0;i<=m;i++) out=max(out,dp4[i]); cout << out << endl; memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); memset(dp3,0,sizeof(dp3)); memset(dp4,0,sizeof(dp4)); memset(num,-1,sizeof(num)); memset(tou,0,sizeof(tou)); memset(shou,0,sizeof(shou)); memset(wuqi,0,sizeof(wuqi)); memset(wuqi2,0,sizeof(wuqi2)); } return 0; }
Problem C: wintermelon的魔界寻路之旅
原题。
#include <iostream> #include <queue> #include <cstring> using namespace std; #define inf 100000000 #define MOD 1000000009 #define MAXV 210 int dx[4] = { 0, 0, 1, -1 }, dy[4] = { 1, -1, 0, 0 }; //用于bfs和dfs搜索的方向 int map[MAXV][MAXV], vol[MAXV][MAXV], n, dis[MAXV][MAXV], flag[MAXV][MAXV], res; //map保存网格,vol保存从0,0到i,j的最短路,n表示网格大小 //dis与flag用于深搜剪枝,res保存的是网格的最短路径 bool istrue(int x, int y){ //判断x,y是否是合理的,即不能超过界限 if (x < n && x >= 0 && y < n && y >= 0 && y < n - x) return true; return false; } void dijstra(){ int x, y, tx, ty, i; queue <int>q; vol[0][0] = map[0][0]; q.push(0); q.push(0); while (!q.empty()){ //求出了所有0,0到i,j的最短路 x = q.front(); q.pop(); y = q.front(); q.pop(); for (i = 0; i<4; i++){ tx = x + dx[i]; ty = y + dy[i]; if (istrue(tx, ty) && vol[tx][ty]>map[tx][ty] + vol[x][y]){ q.push(tx); q.push(ty); vol[tx][ty] = map[tx][ty] + vol[x][y]; } } } res = vol[0][n - 1]; //找出0,0到对称线上的最短路的最小值即是整个网格对称路径的最短路 for (i = 0; i<n; i++) if (res>vol[i][n - i - 1]) res = vol[i][n - i - 1]; } int dfs(int x, int y){ int i, tx, ty; if (x == 0 && y == 0) return 1; //这两句剪枝用的很巧妙,不加的话就会超时,表示x,y是否是第一次搜索, //如果不是的话就直接返回,不用再次计算dis //dis[x][y]表示从x,y到0,0有多少条这样的路径 if (flag[x][y]) return dis[x][y]; flag[x][y] = true; dis[x][y] = 0; for (i = 0; i < 4; i++){ tx = x + dx[i]; ty = y + dy[i]; if (istrue(tx, ty) && vol[x][y] == vol[tx][ty] + map[x][y]){ dis[x][y] = (dis[x][y] + dfs(tx, ty)) % MOD; } } return dis[x][y]; } int main(){ int i, j, key; int t; cin >> t; while (t--) { scanf("%d", &n); for (i = 0; i < n; i++) for (j = 0; j < n; j++) scanf("%d", &map[i][j]); //优化,把下三角的值加到上三角上面,这样就把问题看成从0,0到对称线上的最短路,可以减少很多计算量 for (i = 0; i < n; vol[i][j] = inf, i++) for (j = 0; j < n - i - 1; j++){ map[i][j] = map[i][j] + map[n - j - 1][n - i - 1]; vol[i][j] = inf; } dijstra(); //求出了最短路 memset(flag, false, sizeof(flag)); key = 0; //计算相等路有多少条 for (i = 0; i < n; i++) if (res == vol[i][n - i - 1]) key = (key + dfs(i, n - i - 1)) % MOD; printf("%d\n", key); } return 0; }
Problem D: 二叉树的中序遍历
超级简单题却被坑了,连续俩#就绝对是错的。
#include <iostream> #include <cstring> #include <cstdlib> #include <string> using namespace std; string str; int t; long long int l; bool flag; int last; int now; int main(void) { cin >> t; while(t--) { cin >> str; l=str.length(); flag=1; last=0; for(long long int i=0;i<l;i++) { if(str[i]=='#') last++; else last=0; if(last==2) { flag=0; break; } } if(flag) cout << "yes" << endl; else cout << "no" << endl; } return 0; }
Problem E: 积木积水
水题
#include <iostream> #include <string.h> #include <cstdio> #include <cstdlib> #include <algorithm> #include <string.h> #include <map> #include <set> using namespace std; int T, N; const int INF = 1000010; int arr[INF]; int main(void){ cin >> T; while(T --){ cin >> N; long long ans = 0; int MAXX; for(int i= 0; i < N; i ++){ scanf("%d", &arr[i]); if(i == 0){ MAXX = arr[i]; continue; } if(arr[i] <= MAXX){ ans += MAXX - arr[i]; } else{ MAXX = arr[i]; } } int MINN = 0; for(int i = N - 1; MINN != MAXX && i >= 0; i --){ if(i == N - 1){ MINN = arr[N - 1]; ans -= MAXX - MINN; continue; } if(arr[i] <= MINN){ ans -= MAXX - MINN; } else{ MINN = arr[i]; ans -= MAXX - MINN; } } cout << ans << endl; } }
Problem F: 我是好人4
看队友的吧- -
http://chilumanxi.org/2016/04/21/gdut-2016-%E6%A0%A1%E8%B5%9Bf-%E6%88%91%E6%98%AF%E5%A5%BD%E4%BA%BA4/
Problem G: 我是水题
真是水题。。。
#include <iostream> #include <string.h> #include <cstdio> #include <cstdlib> #include <algorithm> #include <string.h> #include <map> #include <set> using namespace std; int T; int arr[1000]; int main(void){ cin >> T; getchar(); while(T --){ memset(arr, 0, sizeof(arr)); int temp = 0; string tempstr; getline(cin, tempstr); for(int i = 0; i < tempstr.size(); i ++){ if(tempstr[i] <= 'z' && tempstr[i] >= 'a'){ if(!arr[tempstr[i] - 'a']){ arr[tempstr[i] - 'a'] ++; temp ++; } } } cout << temp << endl; } }
相关文章推荐
- php浏览次数累加代码
- 图片像素英寸厘米之间的单位换算
- 问题解决——apple software update无法卸载
- 那些C++牛人的博客
- HDOJ(HDU) 1708 Fibonacci String
- Educational Codeforces Round 12 C.Simple Strings
- HDOJ(HDU) 1708 Fibonacci String
- 数据类型中补充的几个小问题
- 输入一个数字,打印出对应行数的99乘法表
- 方法重写和方法重载;this关键字和super关键字
- 【UNET自学日志】Part9 造成伤害
- good blog about android base
- HDU1010:Tempter of the Bone(DFS)
- 缓存框架 Ehcache Memcache Redis
- Who is YaoGe.(搞笑篇)
- fpmmm(mpm)监控mysql模块安装
- poj1836——Alignment(dp)
- Hive函数大全
- hdu1171 Big Event in HDU --01背包
- uva658