边听音乐边吃东西边比赛……规定时间是4小时,我也就做了不到2小时,测了样例就直接提交了,等了很久很久终于出成绩了……最后967分(满分1000),最后一题有一组数据错了,其他都正确,顺利晋级Silver level~~
Problem 1:CowRace
大意是小牛赛跑,不同时段的速度有所不同,问领先者发生了几次更换。
我是一个时间单位一个时间单位得去模拟的,总时间不长,所以还可以接受。需要注意的边界情况就是:两头牛齐头并进的时候,此时并没有发生领先者的更换;二是最开始的时候,也不算在领先者更换的范围之内。
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <string.h> using namespace std; int main(){ freopen("cowrace.in", "r", stdin); freopen("cowrace.out", "w", stdout); int n, m, t; //speed and time pair<int, int> node1[1005], node2[1005]; int res = 0; cin>>n>>m; //total time t = 0; int leader = -1; for(int i=0; i<n; i++){ cin>>node1[i].first>>node1[i].second; t += node1[i].second; } //cout<<"t: "<<t<<endl; for(int i=0; i<m; i++) cin>>node2[i].first>>node2[i].second; int pos1 = 0, ptr1 = 0; int pos2 = 0, ptr2 = 0; for(int i=1; i<=t; i++){ if(node1[ptr1].second == 0) ptr1++; node1[ptr1].second--; pos1 += node1[ptr1].first; //second cow if(node2[ptr2].second == 0) ptr2++; node2[ptr2].second--; pos2 += node2[ptr2].first; //cout<<"pos1: "<<pos1<<" pos2: "<<pos2<<endl; if(leader == -1){ if(pos1 > pos2) leader = 1; else if(pos1 < pos2) leader = 2; } else if(leader == 1){ if(pos2 > pos1){ res++; leader = 2; } } else if(leader == 2){ if(pos1 > pos2){ res++; leader = 1; } }//end else if //cout<<"leader: "<<leader<<endl; }//end for loop cout<<res<<endl; //system("pause"); return 0; }
Problem2:Breed Proximity
大意是一群牛(很好奇美国人怎么这么喜欢拿牛开涮……)站在一起,每头牛都有一个ID编号,要求出间距小于给定值并且最大的ID号。
最朴素的办法自然是去循环枚举,但牛的数目可以达到50000,O(n*K)的复杂度偏大。我的办法是先进行排序,按照ID从小到大拍,相同ID的按照原始位置排序。然后从后往前进行扫描,找到第一对间隔小于K的牛即为最终结果,扫描到头还没发现则不存在解,复杂度为O(nlgn)。
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <string.h> #include <stdlib.h> using namespace std; struct Node{ int pos; int id; }; Node node[50005]; //sorting int cmp(const void *ele1, const void *ele2){ Node* p1=(Node *)ele1; Node* p2=(Node *)ele2; if((p1->id) == (p2->id)) return (p1->pos)-(p2->pos); else return (p1->id)-(p2->id); } int main(){ freopen("proximity.in", "r", stdin); freopen("proximity.out", "w", stdout); int n,k; cin>>n>>k; for(int i=0; i<n; i++){ cin>>node[i].id; node[i].pos = i; } qsort(node, n, sizeof(Node), cmp); int res = -1; int last = -1; int large=0, small=0; for(int i=n-1; i>0; i--){ if(res >= node[i].id) break; if(node[i].id == node[i-1].id){ if(abs(node[i].pos-node[i-1].pos) <= k) res = max(res, node[i].id); } } cout<<res<<endl; //system("pause"); return 0; }
Problem3:
又是牛……给出各对牛之间的关系(相同品种或者不同品种),然后求共有多少可能的品种组合。
最简单的办法是枚举所有可能性,但3^15是1s内算不完的,考虑到对称性,可以假定第一头牛的品种,最后结果乘以3即可。我想到的另一个优化办法就是:如果一头牛没有说明和其他牛的关系,那么它就可以取3中不同的值,在最终的结果中起到了乘以3的作用。对于其他的,可以建成一个无向图,用floyd算法检查是否存在矛盾(利用“相同品种”具有传递性,不同品种则不具有传递性),若条件有矛盾则结果为0。然后深度搜索来枚举剩下的牛即可。
一开始提交的代码错了一个数据,后来发现是在floyd算法更新时漏了两种情况:如果A和B品种相同,B和C品种不同,那么A和C品种一定不同……另一种情况类似,是A、B不同,B、C相同。
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <string.h> using namespace std; bool flag[20]; vector<int> choice[20]; int multiple = 3; int n, k, relation[16][16]; int res = 0; int ans[20]; void dfs(int index); int main(){ //freopen("assign.in", "r", stdin); //freopen("assign.out", "w", stdout); memset(ans, 0, sizeof(ans)); memset(relation, 0, sizeof(relation)); for(int i=0; i<16; i++) relation[i][i] = 1; cin>>n>>k; for(int i=0; i<k; i++){ int x, y; char str; cin>>str>>x>>y; x--; y--; if(str == 'S'){ relation[x][y] = 1; relation[y][x] = 1; } else if(str == 'D'){ relation[x][y] = -1; relation[y][x] = -1; } } //update status for(int i=0; i<n; i++) for(int j=0; j<n; j++) for(int k=0; k<n; k++){ if(relation[j][i] == 1 && relation[i][k] == 1){ if(relation[j][k] == -1){ cout<<0<<endl; return 0; } else relation[j][k] = 1; } // I forgot these two relaations >< if(relation[j][i]==1 && relation[i][k]==-1){ if(relation[j][k]==1){ cout<<0<<endl; return 0; } else relation[j][k] = -1; } if(relation[j][i]==-1 && relation[i][k]==1){ if(relation[j][k]==1){ cout<<0<<endl; return 0; } else relation[j][k] = -1; } } memset(flag, true, sizeof(flag)); flag[0] = false; for(int i=1; i<n; i++){ if(relation[0][i] == -1){ choice[i].push_back(1); choice[i].push_back(2); } else if(relation[0][i] == 1) flag[i] = false; else{ choice[i].push_back(0); choice[i].push_back(1); choice[i].push_back(2); } } for(int i=0; i<n; i++){ if(flag[i] == false) continue; flag[i] = false; for(int k=0; k<n; k++){ if((i!=k) && (relation[i][k]!=0)) flag[i] = true; } if(flag[i] == false) multiple = multiple*3; } //cout<<"multiple: "<<multiple<<endl; dfs(0); res = res*multiple; cout<<res<<endl; system("pause"); return 0; } void dfs(int index){ if(index >= n){ res++; return; } if(flag[index] == false){ dfs(index+1); return; } int len = choice[index].size(); for(int i=0; i<len; i++){ ans[index] = choice[index][i]; bool check = true; for(int j=0; j<index; j++){ if(flag[j] == false) continue; if(relation[index][j]==1 && ans[index]!=ans[j]){ check = false; break; } else if(relation[index][j]==-1 && ans[index]==ans[j]){ check = false; break; } }//end for loop if(check == true){ dfs(index+1); } } return; }