标签:games assert clu 另一个 make return const top mes
题意:给出所有人比的场数,设计一种方案。赢的人必须连续打下一轮。
能得知2个结论:1:不会有人的场数超过场数和的一半,否则他的对手会有自己。2:要打赢一个人的人至少会打2场,因为他打赢算1场,然后还必须参加下一场。打2场以上的人打的场数和>=所有人的场数和的一半。
这样的话,就用场数多的当胜者,他打的最后一场让他败,换另一个胜场多的当胜者。
实际实现有点困难。特别注意对手不能是自己。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #define mkp make_pair using namespace std; const double EPS=1e-8; const int SZ=10050,INF=0x7FFFFFFF; typedef long long lon; priority_queue<pair<int,int>> pq; int arr[SZ][2]; void work(int n) { pair<int,int> top=pq.top(); pq.pop(); for(int i=1;i<=top.first-1;++i)arr[i][0]=top.second; arr[top.first][1]=top.second; int pos=top.first; if(pos==n)++pos; for(;pos!=n+1;) { top=pq.top(); pq.pop(); for(;top.first&&pos!=n+1;--top.first) { //cout<<pos<<endl; //if(!arr[pos][1])arr[pos++][1]=top.second; if(top.first==1) { arr[pos][1]=top.second; if(pos==n)++pos; } else arr[pos++][0]=top.second; } } pos=1; if(top.first) { for(;top.first;) { if(arr[pos][0]==0)arr[pos++][0]=top.second,--top.first; else if(arr[pos][1])++pos; else arr[pos++][1]=top.second,--top.first; } } for(;!pq.empty();) { top=pq.top(); pq.pop(); for(;top.first;) { if(arr[pos][0]==0)arr[pos++][0]=top.second,--top.first; else if(arr[pos][1])++pos; else arr[pos++][1]=top.second,--top.first; } } } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); lon casenum; //cin>>casenum; //for(lon time=1;time<=casenum;++time) { int n; cin>>n; int sum=0; for(int i=1;i<=n;++i) { int tmp; cin>>tmp; pq.push(mkp(tmp,i)); sum+=tmp; } sum/=2; work(sum); cout<<sum<<endl; for(int i=1;i<=sum;++i) { cout<<arr[i][0]<<" "<<arr[i][1]<<endl; } } return 0; }
标签:games assert clu 另一个 make return const top mes
原文地址:https://www.cnblogs.com/gaudar/p/9771085.html