2017 ACM-ICPC 亚洲区(南宁赛区)英语阅读网络竞赛
来源:互联网 发布:python模块大全下载 编辑:程序博客网 时间:2024/06/10 14:01
题目链接:2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
A. Weather Patterns
题意:有四种天气,给你一个4*4的矩阵,a[i][j]表示从天气i转变为天气j的概率,然后又四个询问(两种),第一种是,给你两个观察序列,问你按照这个观察序列转变的概率是多少,第二种是给你i和j,表示连续若干天都是i天气或j天气的期望为多少
解析:求概率,那不就是一直乘么,求期望,那不就是几何分布的期望么,您就欺负我英语不好吧!!!
#include <bits/stdc++.h>using namespace std;double pc[5][5];int md[2][1000000];int len[2];int x[2];double ans;int main(void){ for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) scanf("%lf",&pc[i][j]); len[0]=0; for(int i=0;true;i++) { scanf("%d",&md[0][i]); len[0]++; if(getchar()=='\n') break; } len[1]=0; for(int i=0;true;i++) { scanf("%d",&md[1][i]); len[1]++; if(getchar()=='\n') break; } scanf("%d%d",&x[0],&x[1]); ans=1.0; for(int i=1;i<len[0];i++) ans*=pc[md[0][i-1]][md[0][i]]; printf("%.8f\n",ans); ans=1.0; for(int i=1;i<len[1];i++) ans*=pc[md[1][i-1]][md[1][i]]; printf("%.8f\n",ans); printf("%.8f\n",1.0/(1.0-pc[x[0]][x[0]])); printf("%.8f\n",1.0/(1.0-pc[x[1]][x[1]])); return 0;}
B. Train Seats Reservation
题意:有一辆火车,有100个火车站台,站台编号为1~100,每个乘客能预定k张火车票,从t1站台上车,从t2站台下车,问你这两火车最少要多少个座位才能满足说有乘客的要求
解析:直接开个数组记录下每个站台的时候有多少个座位被座了,然后算一下最大值输出就可以了,记住先下后上(重点)
#include <bits/stdc++.h>using namespace std;typedef long long ll;ll vis[105];int main(void){ int n; while(scanf("%d",&n)) { if(n==0) { puts("*"); break; } memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) { int s,t; ll k; scanf("%d %d %lld",&s,&t,&k); for(int j=min(s,100);j<min(100,t);j++) vis[j] += k; } ll ans = 0; for(int i=1;i<=100;i++) ans = max(ans,vis[i]); printf("%lld\n",ans); } return 0;}
D. Path Search with Constraints
题意:好像是求什么(1,1)到(I,J)的最短路径的,要求权值最小,根据样例得出的题意大概就是,给你一个矩阵,题面又告诉你了一个转移方程,然后让你输出最小花费,和路径
解析:大概猜出题意了,想着,动态转移方程都告诉我了,直接套不就好了么,输出路径的时候发现,和答案一点都不想,看了半天题目,猜测是有两个状态要多存一个结点吧。试着交了一下,A了,真的是猜了半年的题意:)
#include<bits/stdc++.h>using namespace std;const int INF=0x7ffffff;double dp[40][40];int marix[40][40];char as[1000];pair<int,int> pre[40][40];int main(){ double a,b; scanf("%lf%lf",&a,&b); for(int i=0; i<40; i++) { for(int j=0; j<40; j++) dp[i][j]=INF; } int c1 = 1,c2 = 1; getchar(); while(c1<=6&&gets(as)) { c2 = 1; int len = strlen(as); for(int i=0; i<len;) { if(as[i]>='0' && as[i]<='9') { int tmp = 0; while(as[i]>='0' && as[i]<='9' && i<len) { tmp = tmp*10+as[i]-'0'; i++; } marix[c1][c2++] = tmp; } else i++; } c1++; } dp[1][1]=marix[1][1]; pre[1][1]=make_pair(0,0); for(int i=1; i<c1; i++) { for(int j=1; j<c2; j++) { if(j>2&&i>1) { if(dp[i-1][j-2]+a*(marix[i][j-1]+marix[i][j])<dp[i][j]) { dp[i][j]=dp[i-1][j-2]+a*(marix[i][j-1]+marix[i][j]); pre[i][j]=make_pair(i-1,j-2); } } if(i>1&&j>1) { if(dp[i-1][j-1]+b*marix[i][j]<dp[i][j]) { dp[i][j]=dp[i-1][j-1]+b*marix[i][j]; pre[i][j]=make_pair(i-1,j-1); } } if(j>1&&i>2) { if(dp[i-2][j-1]+a*(marix[i-1][j]+marix[i][j])<dp[i][j]) { dp[i][j]=dp[i-2][j-1]+a*(marix[i-1][j]+marix[i][j]); pre[i][j]=make_pair(i-2,j-1); } } } } vector<pair<int,int> >ans; printf("%.6f\n",dp[c1-1][c2-1]); int x = c1-1,y = c2-1; ans.push_back(make_pair(x,y)); while(x!=1 || y!=1) { int tx = pre[x][y].first; int ty = pre[x][y].second; if(x-tx==2) ans.push_back(make_pair(x-1,y)); else if(y-ty==2) ans.push_back(make_pair(x,y-1)); x = tx,y = ty; ans.push_back(make_pair(tx,ty)); }// for(int i=1;i<c1;i++)// {// for(int j=1;j<c2;j++)// printf("%.1f ",dp[i][j]==INF?0:dp[i][j]);// puts("");// }// for(int i=1;i<c1;i++)// {// for(int j=1;j<c2;j++)// printf("(%d,%d) ",pre[i][j].first,pre[i][j].second);// puts("");// } for(int i=ans.size()-1;i>=0;i--) printf("(%d,%d)\n",ans[i].second,ans[i].first); return 0;}
F. Overlapping Rectangles
题意:矩形面积并
解析:线段树,直接套模板
#include <bits/stdc++.h>using namespace std;const int maxn = 1e4;typedef long long ll;int n;struct node{ ll l, r, h; int d; node() {} node(int l, int r, int h, int d): l(l), r(r), h(h), d(d) {} bool operator< (const node& rhs) const { return h < rhs.h; }} a[maxn];ll cnt[maxn << 2];ll sum[maxn << 2],all[maxn];void push_up(int l, int r, int rt){ if(cnt[rt]) sum[rt] = all[r + 1] - all[l]; else if(l == r) sum[rt] = 0; else sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}void update(int L, int R, int v, int l, int r, int rt){ if(L <= l && r <= R) { cnt[rt] += v; push_up(l, r, rt); return; } int m = (l + r)>>1; if(L <= m) update(L, R, v, l, m, rt << 1); if(R > m) update(L, R, v, m + 1, r, rt << 1 | 1); push_up(l, r, rt);}int main(){ while(scanf("%d", &n)) { if(n==0) { puts("*"); break; } for(int i = 1; i <= n; ++i) { ll x1, y1, x2, y2; scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2); a[i] = node(x1, x2, y1, 1); a[i + n] = node(x1, x2, y2, -1); all[i] = x1; all[i + n] = x2; } n <<= 1; sort(a + 1, a + 1 + n); sort(all + 1, all + 1 + n); int m = unique(all + 1, all + 1 + n) - all - 1; memset(cnt, 0, sizeof cnt); memset(sum, 0, sizeof sum); ll ans = 0; for(int i = 1; i < n; ++i) { int l = lower_bound(all + 1, all + 1 + m, a[i].l) - all; int r = lower_bound(all + 1, all + 1 + m, a[i].r) - all; if(l < r) update(l, r - 1, a[i].d, 1, m, 1); ans += sum[1] * (a[i + 1].h - a[i].h); } printf("%lld\n",ans); } return 0;}
G. Finding the Radius for an Inserted Circle
题意:给你三个半径为R的圆(Ca,Cb,Cc),然后根据这三个圆生成C1,即和之前三个圆相切,然后C2也是类似这样生成的,总之看图就好啦,要求的就是Ck的半径,要直接截断小数点后面的数
解析:其实第一个圆很好求,如下图所示
对于第2个圆,一直到第k个圆来说,求法是一样的,如下图所示
#include <bits/stdc++.h>using namespace std;double ans[15];int main(void){ int l,k; double r; scanf("%d",&l); scanf("%lf",&r); ans[1] = r*2.0/sqrt(3.0)-r; double d = (ans[1]+r)/2.0-ans[1]; for(int i=2;i<=10;i++) { ans[i] = d*d/2.0/(r+d); d -= 2*ans[i]; } l++; while(l--) { scanf("%d",&k); if(k==-1) break; printf("%d %d\n",k,(int)floor(ans[k])); } return 0;}
H. A Cache Simulator
题意:模拟一个缓存器
解析:表示好险队友是计科专业的
#include <bits/stdc++.h>using namespace std;int main(void){ int mcache[64]; memset(mcache,0,sizeof(mcache)); int acnt=0,hcnt=0; while(1) { char c[10]; scanf("%s",c); if(c[0]=='E'&&c[1]=='N') { double ans=100.0*hcnt/acnt; printf("Hit ratio = %.2f%c",ans,'%'); break; } int ad=0; for(int i=0;i<7;i++) { int k; if(c[i]>='A'&&c[i]<='F') k=c[i]-'A'+10; if(c[i]>='0'&&c[i]<='9') k=c[i]-'0'; ad=ad*16+k; } int gid=(ad/16)%64; if(abs(mcache[gid]-ad)<16) { printf("Hit\n"); hcnt++; } else { printf("Miss\n"); mcache[gid]=ad; } acnt++; } return 0;}
I. GSM Base Station Identification
题意:给你10个坐标,问你这10个点在哪个正六边形里面(题目的图片上)
解析:当初感觉这题很麻烦不是特别想写,比赛结束后,发现可以通过把每个正六边形的中心表示出来,然后枚举所有正六边形的中心,判断两点间的距离是是否小于5
#include <bits/stdc++.h>using namespace std;struct point{ double x,y; point() {} point(double _x,double _y):x(_x),y(_y) {}}ans[15],p;double dis(point p1,point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}int main(void){ for(int i=0;i<10;i++) { scanf("%lf %lf",&p.x,&p.y); for(int j=-9;j<=10;j++) { for(int k=-9;k<=10;k++) { //自己在草稿纸上画一下,应该就能发现,六边形的中心坐标满足 point tmp; tmp.x = 5.0*sqrt(3.0)*j+5*sqrt(3.0)/2.0*k; tmp.y = 15.0/2.0*k; if(dis(tmp,p)<=5.0) ans[i] = point(j,k); } } } for(int i=0;i<10;i++) { if(i)printf(", "); printf("[%.f,%.f]",ans[i].x,ans[i].y); } puts(""); return 0;}
J. Minimum Distance in a Star Graph
题意:给你5组长度为n的字符串s和e,问你e要执行多少次交换操作才能使得s和e相等,交换操作的定义为:第一个位置的数字和其他交换,仅此而已
解析:直接bfs即可,(一开始bfs不敢交,后面试了一下,发现竟然是WA了,在队友的提醒下,发现自己看错了题目,以为可以任意换。。。。
#include <bits/stdc++.h>using namespace std;map<long long ,int>maple;struct node{ char s[15]; long long v; int step;}a,b;int n;long long geth(char a[]){ long long res = 0; for(int i=0;i<n;i++) res = res*10+a[i]-'0'; return res;}int bfs(){ a.v = geth(a.s); a.step = 0; queue<node>q; q.push(a); maple[a.v] = 1; while(!q.empty()) { node now = q.front(); q.pop(); if(strcmp(now.s,b.s)==0) return now.step; for(int j=1;j<n;j++) { node tmp = now; swap(tmp.s[0],tmp.s[j]); tmp.v = geth(tmp.s); if(maple.find(tmp.v)!=maple.end()) continue; maple[tmp.v] = 1; tmp.step = now.step+1; q.push(tmp); } } return -1;}int main(void){ int m = 5; scanf("%d",&n); for(int kk=0;kk<m;kk++) { maple.clear(); scanf("%s %s",a.s,b.s); printf("%d\n",bfs()); } return 0;}
L. The Heaviest Non-decreasing Subsequence Problem
题意:让你求一个最重的不严格递增子序列,也就是给你一个长度要你自己算的序列,每一个序列有一个权值,即该元素为负数,权值为0,该元素>=10000,权值为5,否则权值为1,然后让你求一个最大权值和的子序列(不减)
解析:其实把>=10000的元素,重复5次加到原序列中,然后求一次最长不减子序列即可
#include <bits/stdc++.h>using namespace std;const int INF=1<<30;const int maxn=1000007;int a[300000];int b[maxn];int len,n;int v[300000];int dp[maxn];int main(void){ int x; len=0; while(scanf("%d",&x)!=-1) { if(x>=10000) { v[len]=5; a[len]=x%10000; } else if(x<0) { v[len]=0; a[len]=x; } else { v[len]=1; a[len]=x; } len++; } n=0; for(int i=0;i<len;i++) for(int j=0;j<v[i];j++) b[n++]=a[i]; fill(dp,dp+n,INF); for(int i=0;i<n;i++) { *upper_bound(dp,dp+n,b[i])=b[i]; } printf("%d\n",lower_bound(dp,dp+n,INF)-dp); return 0;}
M. Frequent Subsets Problem
题意:给以一个全集U={1,2,…,n},然后又m个全集的子集,现在给你一个α,问你存在几个集合,在这m个集合出现的次数大于等于α*m,输入第一行是n和α,接下来m行分别是m个集合
解析:题目看懂后,应该算是比较好做吧,除去输入不说以外,我的想法是,记录1~n个元素,每个元素在这m个集合里出现的次数,然后答案的集合肯定是这些元素(出现次数大于ceil(α*m))组合起来,那么直接把这些数全都放到一个集合里,然后枚举这个集合的子集是否满足条件,如果满足ans++
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int maxn = 1e5+100;int s[maxn];int vis[maxn];char a[maxn];int main(void){ int n; double b; scanf("%d %lf",&n,&b); int m = 0; getchar(); while(gets(a)) { int len = strlen(a); for(int i=0;i<len;) { if(a[i]>='0'&&a[i]<='9') { int tmp = 0; while(a[i]>='0'&&a[i]<='9'&&i<len) { tmp = tmp*10+a[i]-'0'; i++; } vis[tmp]++; s[m] |= 1<<(tmp-1); } else i++; } m++; } int t = (int)ceil(b*m); int res = 0; for(int i=1;i<=n;i++) { if(vis[i]>=t) res |= 1<<(i-1); } int ans = 0; int sub = res; do { int flag=0; for(int i=0;sub!=0&&i<m;i++) if((sub|s[i])==s[i]) flag++; if(flag>=t) { ans++;// printf("%o\n",sub); } sub = (sub-1)&res; }while(sub!=res); printf("%d\n",ans); return 0;}
- 2017 ACM-ICPC 亚洲区(南宁赛区)英语阅读网络竞赛
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 A. Weather Patterns(阅读题)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 A Weather Patterns(阅读理解)
- 周末训练笔记+ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛+2017 ACM-ICPC 亚洲区(南宁赛区)网络赛(9.23,9.24)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
- ACM 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 B. Train Seats Reservation
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 B.Train Seats Reservation(模拟)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F. Overlapping Rectangles(扫描线)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛: F. Overlapping Rectangles(线段树)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F. Overlapping Rectangles(面积并)
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 Overlapping Rectangles
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 The Heaviest Non-decreasing Subsequence Problem
- B. Train Seats Reservation 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 待补
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 A. Weather Patterns
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 B. Train Seats Reservation
- 购买保健品被骗,如何才能识破保健品消费陷阱呢?
- JAVA基础--内部类
- java的栈,堆,静态区的理解
- MvvmLight中的Messenger详解
- bootstrap打开模态modal窗口引起页面抖动解决办法
- 2017 ACM-ICPC 亚洲区(南宁赛区)英语阅读网络竞赛
- android之存储篇_SQLite数据库_让你彻底学会SQLite的使用
- windows系统 Git Server git服务器自己搭建 (基于 Gitblit or Gogs )
- matlab函数fft
- ie 浏览器 You're trying to decode an invalid JSON String的问题
- Android---fragment动态切换简单使用
- 分页的datatable
- 图片不能百分百显示
- java的重写和重载