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\n", *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\n", *it1++, *it2--);
}else{
it1 = vt3.end()-1,it2 = vt4.begin();
while(it2 < vt4.end())
printf("%d %d\n", *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\n",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\n", (*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\n", (*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\n", (*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\n", (*it1++).second, (*it2++).second);
}
}
return 0;
}