2021. Scarily interesting!
Memory limit: 64 MB
Input
Output
Sample
input | output |
---|---|
5 0 1 4 3 6 6 5 1 3 0 |
5 1 1 5 4 4 2 3 3 2 |
Problem Source: NEERC 2014, Eastern subregional contest
题意:
两个队进行比赛,每个队n个人,现在已知每个人会得多少分。每个人的得分不超过6。比赛进行n回合,每个回合一个队派一个人参赛,每个人只能参赛一次。一个队伍前i个回合的总得分为该队伍派出的前i个人的得分和。现在让你输出一个方案,让比赛尽量不失去悬念。假设第i回合比赛已经没有悬念,那么我们需要输出一个方案,让i尽量的大。
题解:
游戏的输赢不用比根据表已经看出来了,但是怎么比呢?这题不是我读的,开始读错了,以为赢一场得一分,然后贪心做的,不过之后PS发现了读错题,本来应该敲一敲试一试的,但是下午有比赛就再没做,然而自己敲这道题的时候还是出现了小插曲。。。
首先判断两个队伍谁最终会获胜。对于最后会输的队伍,从最强的人派出来参赛,对于最后会赢的队伍,先派最弱的人参赛,这样让比赛上演逆转,悬念一定能保持得最久。很好的思想,是贪心吗?好像是吧。。。
因为这道题是Special Judge 所以下面也是对的,就是先把得分相同的拿出来先比了。。。
先把相同的挑战了,然后在从小到大 从大到小。
#include <bits/stdc++.h> using namespace std; vector<int> vt1[7], vt3, vt2[7],vt4; vector<int>::iterator it1, it2; void ini() { for (int i = 0; i <= 6; ++i) vt1[i].clear(), vt2[i].clear(); vt3.clear(), vt4.clear(); } int main() { int n, a, b ,sum1 , sum2; while (~scanf("%d", &n)) { ini(); sum1=sum2=0; for(int i = 1; i <= n; ++i) scanf("%d", &a), vt1[a].push_back(i),sum1+=a; for(int i = 1; i <= n; ++i) scanf("%d", &b), vt2[b].push_back(i), sum2+=b; for(int i = 0; i <= 6; ++i) { it1 = vt1[i].begin(),it2 = vt2[i].begin(); while (it1 != vt1[i].end() && it2 != vt2[i].end()) printf("%d %d ", *it1++, *it2++); while(it1!=vt1[i].end()) vt3.push_back(*it1++); while(it2!=vt2[i].end()) vt4.push_back(*it2++); } if(sum1>sum2){ it1 = vt3.begin(),it2 = vt4.end() - 1; while(it1 < vt3.end()) printf("%d %d ", *it1++, *it2--); }else{ it1 = vt3.end()-1,it2 = vt4.begin(); while(it2 < vt4.end()) printf("%d %d ", *it1--, *it2++); } } return 0; }
本来用个结构体排序就够了!!!
#include<bits/stdc++.h> #define nn 1100 using namespace std; int n; struct node { int id,val; } a[nn],b[nn]; bool cmp(node xx,node yy) { return xx.val<yy.val; } bool cmp1(node xx,node yy) { return xx.val>yy.val; } int main() { int i; while(scanf("%d",&n)!=EOF) { int suma,sumb; suma=sumb=0; for(i=1; i<=n; i++) { scanf("%d",&a[i].val); suma+=a[i].val; a[i].id=i; } for(i=1; i<=n; i++) { scanf("%d",&b[i].val); sumb+=b[i].val; b[i].id=i; } if(suma>sumb) sort(a+1,a+n+1,cmp),sort(b+1,b+n+1,cmp1); else sort(a+1,a+n+1,cmp1), sort(b+1,b+n+1,cmp); for(i=1; i<=n; i++) printf("%d %d ",a[i].id,b[i].id); } return 0; }
自己又浪了一波,然后set来一发,WA
为什么?弱鸡竟然忘了set里面的值不能相同了,然后在operator重载里面加上
if(a.first==b.first)
return a.second<b.second;就可以了,因为每个i是不同的,这样也就是每个T结构体是不一样的了;
之前还总是想为什么set里面排序不能写成sort那样bool cmp(){}而必须是重载函数的形式(operator重载或者结构体里面operator重载),估计就是为了判断插入的。
这里原本应该用multiset的好不好!!!
还有这里也发现了一个vector与set本质上的不同,之前就知道set是红黑树做的二叉排序树,但是没有注意,set中的iterator是不能加减的,必须用rbegin reverse_iterator这种内置的指针来做,毕竟不是线性结构的,但是vector就比较像数组了(本来就是,废话!)
虽然浪费了点时间,但是还是搞清楚了不少东西的哈,自娱自乐!!!
#include <bits/stdc++.h> using namespace std; struct T{ int first,second; T(int a=0,int b=0){ first = a, second = b; } }; bool operator < (T a ,T b){ return a.first<b.first; } set<T>sset1,sset2; int main() { int n, a, b ,sum1 , sum2; while (~scanf("%d", &n)) { sset1.clear(),sset2.clear(); sum1=sum2=0; for(int i = 1; i <= n; ++i) scanf("%d", &a), sset1.insert( T(a,i) ),sum1+=a; for(int i = 1; i <= n; ++i) scanf("%d", &b), sset2.insert( T(b,i) ), sum2+=b; if(sum1>sum2){ set<T>::iterator it1 = sset1.begin(); set<T>::reverse_iterator it2 = sset2.rbegin(); while(it1 != sset1.end()) printf("%d %d ", (*it1++).second, (*it2++).second); }else{ set<T>::reverse_iterator it1 = sset1.rbegin(); set<T>::iterator it2 = sset2.begin(); while(it2 != sset2.end()) printf("%d %d ", (*it1++).second, (*it2++).second); } } return 0; }
multiset来一发,闲的*疼了又!
#include <bits/stdc++.h> using namespace std; struct T{ int first,second; T(){} T(int a,int b){ first = a, second = b; } }; bool operator < (T a ,T b){ return a.first<b.first; } multiset<T>sset1,sset2; int main() { int n, a, b ,sum1 , sum2; while (~scanf("%d", &n)) { sset1.clear(),sset2.clear(); sum1=sum2=0; for(int i = 1; i <= n; ++i) scanf("%d", &a), sset1.insert( T(a,i) ),sum1+=a; for(int i = 1; i <= n; ++i) scanf("%d", &b), sset2.insert( T(b,i) ), sum2+=b; if(sum1>sum2){ multiset<T>::iterator it1 = sset1.begin(); multiset<T>::reverse_iterator it2 = sset2.rbegin(); while(it1 != sset1.end()) printf("%d %d ", (*it1++).second, (*it2++).second); }else{ multiset<T>::reverse_iterator it1 = sset1.rbegin(); multiset<T>::iterator it2 = sset2.begin(); while(it2 != sset2.end()) printf("%d %d ", (*it1++).second, (*it2++).second); } } return 0; }