A: Ring road【简单搜索】
题意大概是有N个城市,这些城市之间一共有N条单向的公路,每个城市恰好和其他两个城市相连接,每条公路改变方向需要一个花费,现在问如果要满足任何一个城市都能够到达其他任何一个城市最少需要多少花费。
其实可以看到,N个城市有N条公路,每个城市和其他两个城市相连并且路是单向的,所以如果要满足可以到达任何城市那么这N个城市一定是形成了一个环。所以我们直接从编号为1的城市沿着两个方向各走一圈,然后比较哪个花费小就可以了。
#include <cstdio> #include <cstring> #include <vector> #define MAXN 150 using namespace std; vector<int>mp[MAXN],dist[MAXN]; int dfs(int y,int x){ //从x到y if(y == 1) return 0; //如果转了一圈回到1,返回0 int tep = 0; if(mp[y][0] == x) tep = 1; return dfs(mp[y][tep],y) + dist[y][tep]; } int main() { int i,j,n,u,v,w; while(scanf("%d",&n) != EOF){ for(i = 1;i <= n; ++i){ mp[i].clear(); dist[i].clear(); } for(i = 1;i <= n; ++i){ scanf("%d%d%d",&u,&v,&w); mp[u].push_back(v); dist[u].push_back(0); mp[v].push_back(u); dist[v].push_back(w); } int a1 = dfs(mp[1][0],1) + dist[1][0]; int a2 = dfs(mp[1][1],1) + dist[1][1]; printf("%d/n",min(a1,a2)); } }
B:F1 Champions 【简单模拟排序】
给出两种排名规则,然后给出多个比赛的成绩,然后找出两种规则下的冠军。
按照规则排序即可,写的仓促,代码比较丑。
#include <cstdio> #include <iostream> #include <string> #include <map> #include <algorithm> using namespace std; struct Node{ string name; int win[50],point; }a[100]; map<string,int>f; int p[55] = {0,25,18,15,12,10,8,6,4,2,1}; void initial(int n){ for(int i = 1;i <= n; ++i){ for(int j = 1;j <= 50;j++) a[i].win[j] = 0; a[i].point = 0; } } bool cmp1(Node a,Node b){ //先按照分数排序,分数相同按照排名排序 if(a.point == b.point){ for(int i = 1;i <= 50; i++) if(a.win[i] != b.win[i]) return a.win[i] > b.win[i]; } return a.point > b.point; } bool cmp2(Node a,Node b){ //先按照得第一的次数排序,否则按照分数排序,分数再相同按照得第2,第3...的次数排序 if(a.win[1] == b.win[1]){ if(a.point == b.point){ for(int i = 2;i <= 50; i++) if(a.win[i] != b.win[i]) return a.win[i] > b.win[i]; } return a.point > b.point; } return a.win[1] > b.win[1]; } int main() { int i,j,n,T; string str,name1,name2; while(scanf("%d",&T) != EOF){ f.clear(); initial(50); int cont = 1; while(T--){ scanf("%d",&n); for(i = 1;i <= n; ++i){ cin >> str; if(f[str] == 0) f[str] = cont++; a[f[str]].name = str; a[f[str]].win[i] ++; a[f[str]].point += p[i]; } } sort(a+1,a+cont,cmp1); name1 = a[1].name; sort(a+1,a+cont,cmp2); name2 = a[1].name; cout <<name1<<endl<<name2<<endl; } }
C:Sequence of points 【简单数学题】
两个点关于它们的中点对称,题目告诉Mi和M(i-1)两点关于A((i-1)%n)对称,现在给出N和J,(N <= 10 ^ 5, J <= 10 ^ 16),要求求出Mj的坐标。
通过计算可以得到周期是2N,所以只需按题意算出M1到M(2n)即可。PS:悲剧的是由于不常做codeforces,不知道不能写scanf("%lld",&k),导致正确的程序没有AC,郁闷了一晚上。这是近几天第二次栽在这个上面了,无奈至极。换成scanf("%I64lld",&k)就过了。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Point{ int x,y; Point(){} Point(int _x,int _y):x(_x),y(_y){} }a[100002]; Point m[200005]; int main() { int i,j,n; long long k; while(scanf("%d%I64lld",&n,&k) != EOF){ scanf("%d%d",&m[0].x,&m[0].y); for(i = 1;i <= n; i++){ scanf("%d%d",&a[i-1].x,&a[i-1].y); m[i] = Point(2*a[i-1].x-m[i-1].x,2*a[i-1].y-m[i-1].y); } for(i = n+1;i <= 2*n; i++) m[i] = Point(2*a[(i-1)%n].x-m[i-1].x,2*a[(i-1)%n].y-m[i-1].y); k = k%(2*n); printf("%d %d/n",m[k].x,m[k].y); } }
D和E还没有做,过段时间补吧。