Codeforces Round #346 (Div. 2) (659A,659B,659C,659D(几何叉乘),659E(并查集))
Posted piaocoder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #346 (Div. 2) (659A,659B,659C,659D(几何叉乘),659E(并查集))相关的知识,希望对你有一定的参考价值。
Round House
题目链接:
http://codeforces.com/problemset/problem/659/A
解题思路:
The answer for the problem is calculated with a formula ((a?-?1?+?b) n + n) n + 1.
Such solution has complexity O(1).
There is also a solution with iterations, modelling every of |b|‘s Vasya‘s moves by one entrance one by one in desired direction, allowed to pass all the tests.
This solution‘s complexity is O(|b|).
AC代码:
#include <bits/stdc++.h> using namespace std; int main(){ int n,a,b; while(~scanf("%d%d%d",&n,&a,&b)){ int ans = (a+b)%n; if(ans < 0) ans += n; if(ans == 0) ans = n; printf("%d\n",ans); } return 0; }
Qualifying Contest
题目链接:
http://codeforces.com/problemset/problem/659/B
解题思路:
Let‘s consider the participants from every region separately. So for every region we just need to sort all of its participants by their score in non-increasing order. The answer for a region is inconsistent if and only if the score of the second and the third participant in this order are equal, otherwise the answer is the first and the second participant in this order.
The solution complexity is .
AC代码:
#include <bits/stdc++.h> using namespace std; struct node{ string name; int score; node(string _name,int _score){ name = _name; score = _score; } }; int vis[10005]; vector<node> no[10005]; bool cmp(node a,node b){ return a.score > b.score; } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ for(int i = 0; i <= m; i++) no[i].clear(); string name; int region,score; for(int i = 0; i < n; i++){ cin>>name>>region>>score; no[region].push_back(node(name,score)); } for(int i = 1; i <= m; i++){ sort(no[i].begin(),no[i].end(),cmp); int len = no[i].size(); if(len > 2 && no[i][1].score == no[i][2].score) puts("?"); else cout<<no[i][0].name<<" "<<no[i][1].name<<endl; } } return 0; }
Tanya and Toys
题目链接:
http://codeforces.com/problemset/problem/659/C
解题思路:
Our task is to take largest amount of toys Tanya doesn‘t have yet the way the sum of their costs doesn‘t exceed m. To do that one can perform greedy algorithm: let‘s buy the cheepest toy Tanya doesn‘t have at every step, while the amount of money left are sufficient to do that. The boolean array used can be a handle in that, storing true values in indices equal to toy types which Tanya does have at the moment. As soon as 109 money is sufficient to buy no more than 105 toys , used is enough to be sized 2?×?105(we won‘t buy the toys with types numbered greater). So we just need to iterate over the number of type we want to buy, and if corresponding value in used is equal to false, we should buy it, otherwise we can‘t.
The solution complexity is .
One can use the <> data structure (C++ \texttt{std::set}, for example), for storing the types Tanya has at the moment. In this case the complexity is .
AC代码:
#include <bits/stdc++.h> using namespace std; vector<int> v; map<int,int> ma; int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ ma.clear(); v.clear(); int x; for(int i = 0; i < n; ++i){ scanf("%d",&x); ma[x]++; } for(int i = 1; i <= 1000000; ++i){ if(i > m) break; if(!ma[i]){ v.push_back(i); m -= i; } } int len = v.size(); printf("%d\n",len); if(len){ for(int i = 0; i < len-1; ++i) printf("%d ",v[i]); printf("%d\n",v[len-1]); } } return 0; }
Bicycle Race
题目链接:
http://codeforces.com/problemset/problem/659/D
解题思路:
From the track description follows that Maria moves the way that the water always located to the right from her, so she could fall into the water only while turning left. To check if the turn is to the left, let‘s give every Maria‘s moves directions a number: moving to the north —0, moving to the west — 1, to the south — 2 and to the east — 3. Then the turn is to the left if and only if the number of direction after performing a turn dir is equal to the number before performing a turn oldDir plus one modulo 4 .
This solution has complexity O(n).
One can solve this problem in alternative way. Let the answer be equal to x (that means that the number of inner corners of 270degrees equals x, but the number of inner corners of 90 degrees to n?-?x). As soon as the sum of the inner corners‘ values of polygon ofn vertices is equal to 180?×?(n?-?2), then x?×?270?+?(n?-?x)?×?90 equals to 180?×?(n?-?2). This leads us to , being the answer for the problem calculated in O(1).
AC代码:
#include <bits/stdc++.h> using namespace std; struct Point{ int x,y; Point(int x=0,int y=0):x(x),y(y){} // 构造函数,方便代码编写 }po[1005]; typedef Point Vector; //从程序实现上,Vector只是Point的别名 //点-点=向量 Vector operator - (Vector A,Vector B){ return Vector(A.x-B.x,A.y-B.y); } int Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x; } int main(){ int n; while(~scanf("%d",&n)){ for(int i = 0; i <= n; ++i) scanf("%d%d",&po[i].x,&po[i].y); int ans = 0; for(int i = 2; i <= n; ++i){ if(Cross(po[i]-po[i-1],po[i-1]-po[i-2]) < 0)//逆时针的角 ans++; } printf("%d\n",ans); } return 0; }
New Reform
题目链接:
http://codeforces.com/problemset/problem/659/E
解题思路:
One should notice, that for every connected component of the graph the problem could be solved independently, so we just need to solve the problem for any connected graph.
Let this connected graph (of n vertices) contain n?-?1 edge (such is called a tree). If one maintain a DFS from any of its vertex, every edge will be oriented, and each of them could given to its ending vertex, this way every vertex (except the one we launched DFS from, that is the root) will be satisfied by an edge. In this case the answer is equal to 1.
Let‘s then deal with a case when the graph contains more than n?-?1 edges. This graph contains at least one cycle. Let‘s take arbitrary vertex from any of the cycles and launch a DFS (as above) from it. All vertices except chosen will be satisfied, so we are to give an edge to the chosen vertex. As soon as chosen vertex belongs to a cycle, at least one of its edge will not be taken to account in the DFS, so it can be given to a root. This way all the vertices will be satisfied.
Now we are able to solve the task for any connected graph, so we are to divide the graph into a connected components — this can be easily done by DFS or BFS.
The solution complexity is O(n?+?m).
AC代码:
#include <bits/stdc++.h> using namespace std; const int N = 100005; int fa[N],tot[N],TOT[N]; int findset(int x){ if(fa[x] == x) return fa[x]; return fa[x] = findset(fa[x]); } int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ memset(tot,0,sizeof(tot)); memset(TOT,0,sizeof(TOT)); for(int i = 1; i <= n; ++i){ fa[i] = i; tot[i] = 1; TOT[i] = 0; } int u,v; for(int i = 1; i <= m; ++i){ scanf("%d%d",&u,&v); u = findset(u),v = findset(v); if(u == v) TOT[u]++; else{ fa[u] = v; tot[v] += tot[u]; TOT[v] += TOT[u] + 1; tot[u] = TOT[u] = 0; } } int ans = 0; for(int i = 1; i <= n; ++i){ findset(i); if(fa[i] == i) ans += tot[i] > TOT[i]? 1 : 0; } printf("%d\n", ans); } return 0; }
以上是关于Codeforces Round #346 (Div. 2) (659A,659B,659C,659D(几何叉乘),659E(并查集))的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #346 (Div. 2) (659A,659B,659C,659D(几何叉乘),659E(并查集))
Codeforces Round #436 E. Fire(背包dp+输出路径)
[ACM]Codeforces Round #534 (Div. 2)
CodeForces - 346A Alice and Bob博弈