【组队补题题】The Seventh Hunan Collegiate Programming Contest Semilive

来源:互联网 发布:如何开个淘宝网店 编辑:程序博客网 时间:2024/05/05 11:14

题目链接:点击打开链接

B 【UVA 12290】 Counting Game


D 【UVA 12292】Polyomino Decomposer

将给出的图形中的*按照顺序标记,枚举状态,然后判断这个状态是否可行

#include <bits/stdc++.h>using namespace std;typedef pair<int, int>pii;int n;char s[15][15], a[15][15];int px[25], py[25], num, cnt, xi, yi;int vis[25][25], dir[4][2]={0,1,1,0,0,-1,-1,0};int vm[15][15], tot;char cc[15][15];queue<pii>q;struct node{int x, y;}id[25];int bfs(){while(!q.empty()) q.pop();q.push(make_pair(xi, yi));int tmp=1;id[tmp-1].x=xi, id[tmp-1].y=yi;while(!q.empty()){pii u = q.front(); q.pop();vis[u.first][u.second]=0;for(int i=0; i<4; i++){int xx=u.first+dir[i][0], yy=u.second+dir[i][1];if(xx<0 || xx>=n || yy<0 || yy>=n) continue;if(vis[xx][yy]==0) continue;if(s[xx][yy]=='.') continue;vis[xx][yy]=0, tmp++, q.push(make_pair(xx, yy));id[tmp-1].x=xx, id[tmp-1].y=yy;}}return tmp;}void check(int xx, int yy){int len=-1;memset(vm, 0, sizeof(vm));for(int i=0; i<n; i++){for(int j=0; j<n; j++){cc[i][j] = a[i][j];}}for(int i=0; i<n; i++){for(int j=0; j<n; j++){if(s[i][j]=='*' && vm[i][j]==0){len++, xx=i, yy=j;cc[i][j]='A'+len, vm[i][j]=1;for(int k=1; k<num; k++){int cx=id[k].x-id[k-1].x;int cy=id[k].y-id[k-1].y;xx+=cx, yy+=cy;if(xx<0 || xx>=n || yy<0 || yy>=n) return;if(vm[xx][yy]) return;if(s[xx][yy]=='.') return;vm[xx][yy]=1, cc[xx][yy]='A'+len;}}}}if(tot==-1 || tot>len+1){//tot:给出的图形可以由tot个基本图形组成,tot越小,字典序越小 for(int i=0; i<n; i++){for(int j=0; j<n; j++){a[i][j] = cc[i][j];}}tot=len+1;}return;}int main(){ while(~scanf("%d", &n)) { if(n==0) break; xi=yi=-1, cnt=0, tot=-1; for(int i=0; i<n; i++){ scanf("%s",   s[i]); for(int j=0; j<n; j++){ if(s[i][j]=='*') { a[i][j]='A'+cnt; px[cnt]=i, py[cnt]=j, cnt++; if(xi==-1) xi=i, yi=j; } else a[i][j]='.'; } a[i][n]='\0'; }  for(int i=3; i<(1<<cnt); i+=2)  { if(i&1) { num=1; bool flag; memset(vis, 0, sizeof(vis)); for(int j=1; (1<<j)<=i; j++) { int sss = 1<<j; if(sss&i) { vis[px[j]][py[j]]=1; num++; } } if(cnt%num || cnt==num) continue; if(num == bfs()) flag=true;//bfs检验这num个点是不是相邻的  else flag=false; if(flag) check(xi, yi);//验证给出的图形能不能由这num个点组成  } } for(int i=0; i<n; i++) printf("%s\n", a[i]); printf("\n"); }return 0;}

E 【UVA 12293】Box Game(博弈,找规律)

2 先手必胜

3 先手必败

4 5 6 先手必胜

7 先手必败

8 9 10 11 12 13 14 先手必胜

15 先手必败……

如果面对的情况是:在(n+1)/2 ~n-1中存在先手必败点,这种情况是先手必胜,否则先手必败

分析数据就会发现只有n=2^x-1时先手必败

#include <bits/stdc++.h>using namespace std; int a[30];void init(){int ans=1;for(int i=1; i<30; i++){ans*=2;a[i]=ans;}}int main(){int n;init();while(scanf("%d", &n)){if(n==0) break;int flag=0, ans=1;for(int i=1; i<30; i++){if(n==a[i]-1) flag=1; }if(flag) printf("Bob\n");else printf("Alice\n");}return 0;}


F 【UVA 12294】RPG battles

题意:玩游戏,一开始有p(1<=p<=100)能量,有n(1<=n<=1000)个怪,每个怪有六种指标,p1p2t1t2w1w2(1<=p1<p1<=100,1<=t2<t1<=100,0<=w1,w2<=10),打每个怪的时间计算方式是:t1-(p-p1)*(t2-t1)/(p2-p1),当然如果p小于p1,不能打死怪物,输出Impossible,如果p大于p2,时间就是t2。每打死一只怪就能得到奖励技能牌,一类牌w1张,二类牌w2张,一类牌可以将能量值+1,二类牌可以将能量值翻倍,每次可以将奖励牌用完或者不用或用掉部分,怪只能按照顺序一个一个打,一开始手里没有技能牌问最后要是能将所有的怪打死最少需要多少时间?

解题思路:能量值最大都是100,并且能量值越大,杀怪的时间越少,所以我们要在不影响结果的情况下让能量值尽可能的大,那么一类牌遇到一张用掉一张,利用两个优先队列队列枚举每次用的二类牌的张数,输出最少时间。

#include <bits/stdc++.h>using namespace std;struct node{int  wi;double pi,time;friend bool operator < (const node n1, const node n2){return n1.time > n2.time;} }s, e;int a[10];void init(){int ans=1;a[0]=1;for(int i=1; i<=10; i++){ans*=2;a[i] = ans;}}priority_queue<node>q[2];int main(){init();int n;double m;double p, pp, t, tt;int w, ww;while(~scanf("%d%lf", &n, &m)){if(n==0 && m==0) break;while(!q[0].empty()) q[0].pop();while(!q[1].empty()) q[1].pop();scanf("%lf%lf%lf%lf%d%d", &p, &pp, &t, &tt, &w, &ww);int f=1, ff=0, flag=0;if(m<p) flag=1;else{s.pi=m, s.wi=ww;if(s.pi>pp) s.time=tt;else s.time=t-(t-tt)*(s.pi-p)/(pp-p);if(w) s.pi+=w;q[0].push(s);}for(int i=1; i<n; i++){scanf("%lf%lf%lf%lf%d%d", &p, &pp, &t, &tt, &w, &ww);if(flag) continue; int vv=0;while(!q[ff].empty()){s=q[ff].top(); q[ff].pop();for(int i=0; i<=s.wi; i++){e.pi=s.pi*a[i];if(e.pi<p) continue;else if(e.pi>pp) e.time=s.time+tt;else e.time=s.time+t-(t-tt)*(e.pi-p)/(pp-p);e.wi=s.wi-i+ww;if(w) e.pi+=w;q[f].push(e);vv=1;if(e.pi-w>=100) break;}}if(vv==0) flag=1;swap(ff, f);}if(flag) printf("Impossible\n");else printf("%.2lf\n", q[ff].top().time);}return 0;}


G 【UVA 12295】Optimal Symmetric Paths(建图&&最短路&&搜索)

题意:一个n*n的棋盘,每格棋盘上都有一个数字,求从(1,1)开始走到(n,n)路径的条数(可以往上下左右四个方向走),路径满足以下条件:1、关于对角线对称 2、路径上的所有点的和最小

解题思路:将对角线下方的方格里的值加到对角线上方,从(0, 0)开始找到一条通向对角线的路,那么这条路上的和就是从(0, 0)走到(n-1, n-1),并且路线关于对角线对称。点(i, j)记为第i*n+j个点。建图,将相邻两点连通,用最短路算法求出从起始点到对角线上方的点的最短距离,同时用vector容器fa[v]来记录到能到点v的点,从对角线dis最小的点开始反向搜路径条数。

#include <bits/stdc++.h>using namespace std;#define ll long longconst int mod=1e9+9;const int N=150;const int maxm=3e5;int n, a[N][N];int head[maxm], dir[4][2]={0,1,1,0,0,-1,-1,0};queue<int>q;vector<int>fa[maxm];int to[maxm], w[maxm], nxt[maxm];int tot, dis[maxm];ll dp[maxm];bool vis[maxm];void init(){memset(head, -1, sizeof(head));tot=0;while(!q.empty()) q.pop();memset(dis, 0x3f3f3f3f, sizeof(dis));memset(vis, 0, sizeof(vis));for(int i=0; i<maxm; i++) fa[i].clear();memset(dp, 0, sizeof(dp));}void input(){for(int i=0; i<n; i++){for(int j=0; j<n; j++) scanf("%d", &a[i][j]);}for(int i=0; i<n-1; i++){for(int j=0; j<n-i-1; j++){a[i][j]+=a[n-1-j][n-i-1];}}}void addedge(int u, int v, int wi){to[tot]=v, nxt[tot]=head[u], w[tot]=wi, head[u]=tot++;}void BuildGraph(){for(int i=0; i<n-1; i++){for(int j=0; j<n-i-1; j++){for(int k=0; k<4; k++){int xi=i+dir[k][0];int yi=j+dir[k][1];if(xi<0||xi>=n||yi<0||yi>=n) continue;int u=i*n+j, v=xi*n+yi;addedge(u, v, a[xi][yi]);}}}}void spfa(){int u=0, v, wi;q.push(u);vis[u]=1, dis[u]=0;while(!q.empty()){u=q.front(); q.pop();vis[u]=false;for(int i=head[u]; i!=-1; i=nxt[i]){v=to[i], wi=w[i];if(dis[v]==dis[u]+wi){fa[v].push_back(u);}if(dis[v]>dis[u]+wi){fa[v].clear();dis[v]=dis[u]+wi;fa[v].push_back(u);if(!vis[v]) vis[v]=true, q.push(v);}}}}ll dfs(int u){if(u==0) dp[u]=1;ll ret=0;if(dp[u]) return dp[u];for(int i=0; i<fa[u].size(); i++){ret = (ret+dfs(fa[u][i]))%mod;}return dp[u]=ret;}int main(){while(~scanf("%d", &n)){if(n==0) break;init();input();BuildGraph();spfa();int minx=0x3f3f3f3f;for(int i=0; i<n; i++) {int j=n-1-i;minx = min(minx, dis[i*n+j]);}ll ans=0;for(int i=0; i<n; i++){int j=n-1-i;if(dis[i*n+j]==minx) {ans = (ans+dfs(i*n+j))%mod;} }printf("%d\n", ans);}return 0;}/*21 11 131 1 11 1 12 1 1*/

H 【UVA 12296】 Pieces and Discs


I  【UVA 12297Super Poker


J 【UVA 12298】 Super Poker II


K 【UVA 12299】 RMQ with Shifts

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 铁锅炒菜菜发黑怎么办 红豆沙馅太稀了怎么办 买的豆沙馅太稀怎么办 做的豆馅稀了怎么办 包豆沙包馅稀了怎么办 软件自定义权限重名怎么办 窗户外有垃圾桶怎么办 菜地里有蚂蚁怎么办 灯光吸引的飞虫怎么办 广告机格式化了怎么办 proe约束冲突了怎么办 中午考试想睡觉怎么办 喝了红茶睡不着怎么办 考试前状态不好怎么办 考前紧张睡不着觉怎么办 通宵失眠第二天怎么办 考试前睡不着觉怎么办 一到晚上睡不着怎么办 明天考试听力差怎么办 天天晚上睡不着觉怎么办 因紧张睡不着觉怎么办 房卡找不到了怎么办 马代不会英文怎么办 剩下的蒸米饭怎么办 临时牌照违法了怎么办 打12345不管用怎么办 省政府改变了中央文件怎么办 应聘时学历不够怎么办 做导游学历不够怎么办 市长热线打不通怎么办 12315网站不受理怎么办 法律文书生效前转后财产怎么办 打12345投诉没用怎么办 单位医保停了怎么办 iphonex开不了机怎么办 会计证三年没检怎么办 银行工作人员态度不好怎么办 生殖保健服务证怎么办 关机后自动开机怎么办 大连卖房户口怎么办 在警务室被辅警骂了怎么办