2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2)
A:
英语阅读题,没读懂题意,这个题出的严重不好,有兴趣的可以做一下,从后往前求即可;
B:
题让你求每一步操作之后能mess up的数字(1-100)。每一步操作可能是加减乘除,mess up的定义是出现负数或者小数。
按照题意进行模拟就行了,注意坑点:mess up的数字不会再次进行操作。(比如4 -> 4/3 -> 4/3*3这种情况)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 1e6+5; 12 13 int n; 14 bool vis[1005]; 15 double a[N], x[N]; 16 string op[N]; 17 18 int main() 19 { 20 cin >> n; 21 rep(i, 1, n) cin >> op[i] >> x[i]; 22 rep(i, 1, 100) a[i] = i; 23 mem(vis, false); 24 int ans = 0; 25 rep(i, 1, 100){ 26 rep(j, 1, n){ 27 int res = a[i]; 28 if(a[i] < 0 || res*1.0 != a[i]) continue; 29 if(op[j][0] == 'A') a[i] += x[j]; 30 if(op[j][0] == 'S') a[i] -= x[j]; 31 if(op[j][0] == 'M') a[i] *= x[j]; 32 if(op[j][0] == 'D') a[i] = a[i]*1.0/x[j]; 33 } 34 //cout << "a[i]: " << a[i] << endl; 35 int res = a[i]; 36 if(a[i] < 0 || res*1.0 != a[i]) { vis[i] = true; ans++; } 37 } 38 cout << ans << endl; 39 return 0; 40 }
C:
按照题意说求最低的可以让鸡蛋破碎的楼层ans1, 和不能破碎的最高楼层 ans2;
而且告诉你所有 <= safe都是安全的,所有 >= broken的都是不安全的。那么按照题意找出 max[safe] 和 min[broken];
答案 ans1 = max[safe]+1; ans2 = min[broken]-1;
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 1e6+5; 12 13 int n, k, x, vis[N]; 14 string s; 15 16 int main() 17 { 18 cin >> n >> k; 19 int ans1 = k, ans2 = 1; 20 rep(i, 1, n){ 21 cin >> x >> s; 22 if(s[0] == 'S') ans2 = max(ans2, x); 23 else ans1 = min(ans1, x); 24 } 25 //cout << "ans1: " << ans1 << " ans2: " << ans2 << endl; 26 cout << ans2+1 << " " << ans1-1 << endl; 27 return 0; 28 }
D:
一个 n*m 的方格,每个格子都有权值k,每一步可以上下左右四个方向走k步;求左上到右下的最少步数;
简单bfs问题,一步变成k步就好;
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 505; 12 13 int n, m, G[N][N], dir[4][2] = {0,1,0,-1,1,0,-1,0}; 14 string s; 15 bool vis[N][N]; 16 struct Node{ 17 int x, y, cnt, len; 18 Node(int _x, int _y, int _len, int _cnt){ 19 x = _x; y = _y; len = _len; cnt = _cnt; 20 } 21 }; 22 bool judge(int x, int y){ 23 if(x < 1 || x > n || y < 1 || y > m || vis[x][y]) return false; 24 return true; 25 } 26 void bfs(){ 27 queue <Node> Q; 28 mem(vis, false); 29 Q.push(Node(1, 1, G[1][1], 0)); 30 vis[1][1] = true; 31 while(!Q.empty()){ 32 Node h = Q.front(); 33 Q.pop(); 34 int xx = h.x, yy = h.y, lenn = h.len, cntt = h.cnt; 35 if(xx == n && yy == m){ 36 cout << cntt << endl; 37 return ; 38 } 39 rep(i, 0, 3){ 40 int xi = xx+dir[i][0]*lenn, yi = yy+dir[i][1]*lenn; 41 if(judge(xi, yi)){ 42 vis[xi][yi] = true; 43 Q.push(Node(xi, yi, G[xi][yi], cntt+1)); 44 } 45 } 46 } 47 cout << "IMPOSSIBLE" << endl; 48 return ; 49 } 50 int main() 51 {IO; 52 //FIN; 53 while(cin >> n >> m){ 54 rep(i, 1, n){ 55 cin >> s; 56 rep(j, 0, m-1) G[i][j+1] = (s[j]-'0'); 57 } 58 bfs(); 59 } 60 return 0; 61 }
E:
给定一个字符串,只含有小写字母,让你求最少删除多少个字符之后,这个字符串的不同字符个数 <= 2;
用个数组下标代表字符,然后求个数+sort,结果就是把前24个加起来。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 1e6+5; 12 13 string s; 14 int a[30]; 15 16 int main() 17 { 18 cin >> s; 19 rep(i, 0, s.size()-1) a[s[i]-'a']++; 20 sort(a, a+26); 21 int ans = 0; 22 rep(i, 0, 23) ans += a[i]; 23 cout << ans << endl; 24 return 0; 25 }
F:
题意忘了, ans = max(ans, a[i]+a[n-i]); sort排序一下,遍历所有i即可;
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 1e6+5; 12 13 int n, a[N]; 14 15 int main() 16 { 17 cin >> n; 18 rep(i, 1, n) cin >> a[i]; 19 sort(a+1, a+n+1); 20 int ans = 2e6+5; 21 rep(i, 1, n/2) ans = min(ans, a[i]+a[n-i+1]); 22 cout << ans << endl; 23 return 0; 24 }
G:
签到题,按结构体排序
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 1e6+5; 12 13 int n; 14 struct Node{ 15 string s1, s2; 16 bool operator < (const Node &r) const { 17 if(s2 == r.s2) return s1 < r.s1; 18 return s2 < r.s2; 19 } 20 }node[105]; 21 22 int main() 23 { 24 cin >> n; 25 rep(i, 1, n) cin >> node[i].s1 >> node[i].s2; 26 sort(node+1, node+n+1); 27 rep(i, 1, n) cout << node[i].s1 << " " << node[i].s2 <<endl; 28 return 0; 29 }
H:
给定n段任务的三个属性 start(开始时间), val(价值), len(持续时间);
每一段时间都只能允许进行一种任务,现在求怎么安排可以得到一个最大的 tolval,输出这个最大的 tolval;
动态规划题,
计dp[i]表示时间i之前最多能获得的fun值,初始化为0. 将所有活动按开始时间排序,时间从j=0开始,活动从i=1开始,
对于每一个时间点,看是否有活动i在这个时间点开始,如果有,则更新dp[j+a[i].w]=max(dp[j+a[i].w],dp[j]+a[i].fun);
还有记得传递dp[j]给dp[j+1],dp[j+1]=max(dp[j+1],dp[j),因为前j时间可以获得的fun,j+1的时间也一定可以获得。(尊重版权 By - QAQ学长)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 6 7 struct st{ 8 int s,l,v; 9 }a[300005]; 10 bool cmp(st b,st c){ 11 return b.s<c.s; 12 } 13 int dp[2000005]; 14 int main(){ 15 IO; 16 int n; 17 int mx=0; 18 while(cin>>n){ 19 memset(dp,0,sizeof(dp)); 20 for(int i=1;i<=n;i++){ 21 cin>>a[i].s>>a[i].v>>a[i].l; 22 mx=max(mx,a[i].s+a[i].l); 23 } 24 sort(a+1,a+1+n,cmp); 25 int i=1; 26 int result; 27 for(int j=0;j<=mx;j++){ 28 for(;i<=n;i++){ 29 if(a[i].s==j){ 30 dp[j+a[i].l]=max(dp[j+a[i].l],dp[j]+a[i].v); 31 } 32 else break; 33 } 34 dp[j+1]=max(dp[j+1],dp[j]); 35 } 36 cout<<dp[mx]<<endl; 37 } 38 return 0; 39 }
I:
给定两个三角形的三条边,求能不能拼成矩形。拼成矩形需要满足两个条件;
1、每条边相等。 2、两个都是直角三角形;
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 1e6+5; 12 13 int a[5], b[5]; 14 15 int main() 16 { 17 rep(i, 1, 3) cin >> a[i]; 18 rep(i, 1, 3) cin >> b[i]; 19 sort(a+1, a+4); sort(b+1, b+4); 20 21 int ok = 1; 22 rep(i, 1, 3) if(a[i] != b[i]) ok = 0; 23 if(ok){ 24 if(a[1]*a[1]+a[2]*a[2] != a[3]*a[3]) ok = 0; 25 } 26 cout << (ok ? "YES" : "NO") << endl; 27 return 0; 28 }
J:
给你n个齿轮的圆心和半径,求第一个齿轮和最后一个齿轮的三种关系(保证出入数据不会存在两个齿轮相交的情况);
1、这个齿轮系统根本无法工作;
2、两个齿轮相离;
3、齿轮系统工作并且两个齿轮相连 (输出角速度的反比,逆向多输出一个负号);
解法:
1. 最多只有1000个齿轮,因此我们可以先利用 n^2 的算法暴力判断每两个齿轮之间是否相切(即就是两圆相切);
2. 对于相切的两个齿轮,我们可以建一条双向边,这样的话就转化成一个简单的图的问题;
3. 对于不能工作的情况就是样例三的那种情况,对于一个齿轮来说,它可以有多个不同的路径来带动它,但是存在带动的方向不一致。
即就是一个顺时针,一个逆时针。这种情况就是不能工作的。
4. 可以发现距离1号齿轮距离为奇数的齿轮都是都是和1号反向,偶数的都是同向,因此我们可以利用bfs来解决该问题;
5. 利用bfs来求每个点到一号齿轮的距离,如果有多个路径到达该齿轮,判断是不是3的不能工作的情况。最后判断是不是可以到达n号齿轮即可;
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long LL; 10 typedef pair<int, int> PIR; 11 const int N = 1e+5; 12 13 int n, use, stu[N]; 14 bool vis[N]; 15 vector <int> G[N]; 16 struct Node{ 17 LL x, y; 18 LL r; 19 }node[N]; 20 21 bool judge(int i, int j){ 22 LL xi = node[i].x-node[j].x, yi = node[i].y-node[j].y; 23 LL ri = node[i].r+node[j].r; 24 return (xi*xi+yi*yi) == ri*ri; 25 } 26 void Test(){ 27 cout << "-----------TEST----------" << endl; 28 rep(i, 1, n){ 29 cout << i << ": "; 30 rep(j, 0, (int)G[i].size()-1) cout << G[i][j] << " "; 31 cout << endl; 32 } 33 cout << endl; 34 } 35 36 void bfs(){ 37 queue <PIR> Q; 38 mem(stu, -1); 39 mem(vis, false); 40 use = 1; 41 Q.push(PIR(1, 0)); 42 stu[1] = 0; 43 vis[1] = true; 44 while(!Q.empty()){ 45 PIR pir = Q.front(); Q.pop(); 46 int u = pir.first, st = pir.second; 47 if(u == n){ 48 if(st^0 == 1) cout << "-"; 49 LL gcd = __gcd(node[n].r, node[1].r); 50 cout << node[1].r/gcd << ":" << node[n].r/gcd << endl; 51 return ; 52 } 53 rep(i, 0, (int)G[u].size()-1){ 54 int v = G[u][i]; 55 if(stu[v] != -1 && stu[v]^st == 0){ 56 cout << "The input gear cannot move." << endl; 57 return ; 58 } 59 60 if(vis[v]) continue; 61 if(stu[v] == -1 || (stu[v] != -1 && stu[v]^st == 1)){ 62 stu[v] = st^1; 63 vis[v] = true; 64 Q.push(PIR(v, st^1)); 65 } 66 } 67 } 68 cout << "The input gear is not connected to the output gear." << endl; 69 return ; 70 } 71 int main() 72 {IO; 73 //FIN; 74 cin >> n; 75 rep(i, 1, n) cin >> node[i].x >> node[i].y >> node[i].r; 76 rep(i, 1, n) rep(j, i+1, n) if(judge(i, j)) { G[i].pb(j); G[j].pb(i); } 77 //Test(); 78 bfs(); 79 return 0; 80 }
K:
给你一个n*m的矩阵,每个点有一个值,现在有k步操作,求k步之后矩阵种的不同元素的个数;
每一步操作将矩形的每个点变成周围数的和的平均值,如果超过边界,则从另外的边界补全;
n, m <= 100; k <= 9;直接暴力去变化就行了,注意每个点的值需要用分数的形式表示; (尊重版权 By - Yimismi)
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i = a;i <= b;++ i) 4 #define per(i,a,b) for(int i = a;i >= b;-- i) 5 #define mem(a,b) memset((a),(b),sizeof((a))) 6 #define FIN freopen("in.txt","r",stdin) 7 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 8 #define pb push_back 9 typedef long long ll; 10 struct Node 11 { 12 ll up, down; 13 Node() {}; 14 Node(ll a, ll b) {up = a, down = b;} 15 } node[2][105][105]; 16 bool operator < (const Node& t1, const Node& t2) 17 { 18 return t1.up*t2.down < t1.down*t2.up; 19 } 20 Node operator + (const Node& t1, const Node& t2) 21 { 22 Node ans; 23 24 ans.down = t1.down*t2.down; 25 ans.up = t1.up*t2.down + t1.down*t2.up; 26 ll g = __gcd(ans.down, ans.up); 27 ans.down /= g; 28 ans.up /= g; 29 return ans; 30 } 31 int w, h, d; 32 void du(int x) 33 { 34 for(int i = 0; i < h; i++) 35 { 36 for(int j = 0; j < w; j++) cout << node[x][i][j].up << "/" << node[x][i][j].down << " " ; cout << endl; 37 } 38 } 39 Node solve(int u, int x, int y) 40 { 41 Node ans = Node(0, 1); 42 for(int i = (x - 1 + h)%h, time = 0; time < 3; time++, i = (i + 1)%h) 43 { 44 for(int j = (y - 1 + w)%w, time1 = 0; time1 < 3; time1++, j = (j + 1)%w) 45 ans = ans + node[u][i][j]; 46 } 47 48 ans.down *= 9; 49 ll g = __gcd(ans.up, ans.down); 50 ans.up /= g; 51 ans.down /= g; 52 //;cout << "-- " << x << " " << y << " "<< ans.up << " " << ans.down << endl; 53 return ans; 54 } 55 void foo(int u) 56 { 57 int v = u^1; 58 for(int i = 0; i < h; i++) 59 { 60 for(int j = 0; j < w; j++) 61 { 62 node[v][i][j] = solve(u, i, j); 63 } 64 } 65 66 } 67 set<Node> st; 68 int main() 69 {IO; 70 while(cin >> w >> h >> d) 71 { 72 for(int i = 0; i < h; i++) 73 for(int j = 0; j < w; j++) 74 { 75 int d; 76 cin >> d; 77 node[0][i][j].down = 1; 78 if(d == 0) node[0][i][j].up = 0; 79 else node[0][i][j].up = 1; 80 } 81 for(int i = 0; i < d; i++) foo(i&1); 82 st.clear(); 83 for(int i = 0; i < h; i++) 84 for(int j = 0; j < w; j++) 85 { 86 st.insert(node[d&1][i][j]); 87 // cout << node[d&1][i][j].up << " " << node[d&1][i][j].down << endl; 88 } 89 cout << st.size() << endl; 90 91 } 92 return 0; 93 }