CF div2 601
比赛AB两个题,菜,B题据说是个错的。emmm
A题,水题
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[])
{
//freopen("A.txt","r",stdin);
int t;
cin>>t;
while(t--) {
int a,b;
cin>>a>>b;
int c=abs(a-b);
int ans = c/5;
c=c%5;
ans+=c/2;
c=c%2;
ans+=c;
cout<<ans<<endl;
}
return 0;
}
B题,给你n个人,每个人有一个冰箱,m条链子,链接n个冰箱,当一个人有链接这个冰箱的所有链子的密码,可以打开这个冰箱,求每个冰箱都是每个人私有的链子权值和的最小代价。
明显,需要有环,直接一个大环。因为可以连重边,所以剩下的m-n条边全部连权值最小的,
但是赛后,好像有情况不符合,变成了一个错题。
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int maxn = 1e3+10;
struct node
{
int x;
int id;
}a[maxn];
bool cmp(node A,node B) {
return A.x<B.x;
}
int main()
{
//freopen("B.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--) {
int n,m;
scanf("%d%d",&n,&m);
int ans = 0;
rep(i,1,n) {
cin>>a[i].x;
ans+=a[i].x;
a[i].id=i;
}
if(m<n||n==2) {
puts("-1");
continue;
}
if(m==n) {
printf("%d\n",ans*2);
rep(i,1,n) {
if(i==n) printf("%d 1\n",i);
else printf("%d %d\n",i,i+1);
}
continue;
}
ans*=2;
m-=n;
int f=0;
sort(a+1,a+1+n,cmp);
ans=ans+m*(a[1].x+a[2].x);
printf("%d\n",ans);
rep(i,1,n) {
if(i==n) printf("%d 1\n",i);
else printf("%d %d\n",i,i+1);
}
while(m--) {
printf("%d %d\n",a[1].id,a[2].id);
}
}
return 0;
}
C题,意思是给你一个n个数排列,构成n-2个三元组(连续),然后可以打乱三元组的顺序和三元组内元素的顺序。叫你还原这个排列。
容易知道,最开始和最后的元素出现次数为1,还有两个元素(出现次数)分别在最开始和最后的元素所在三元组中,剩下的元素出现次数全为3。
首先,找到出现次数为1 的,根据这个三元组继续往后推,直到推到最后一个。
记录每一组的三个元素和每个元素出现的组数,然后往后推,记录一下前面的组数,找当前b,c出现组数相同的且和前面不同的。此时将这个组的另外一个元素推进答案,然后a=b,b=c;c=新元素。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
vector<int>p[maxn];
int e[maxn][4];
int cnt[maxn];
vector<int>ans;
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n-2;i++) {
int x,y,z;
cin>>x>>y>>z;
cnt[x]++;
cnt[y]++;
cnt[z]++;
e[i][1]=x;
e[i][2]=y;
e[i][3]=z;
p[x].push_back(i);
p[y].push_back(i);
p[z].push_back(i);
}
int start;
for(int i=1;i<=n;i++) {
if(cnt[i]==1) {
start = i;
break;
}
}
ans.push_back(start);
int id;
for(int i=0;i<p[start].size();i++) {
id = p[start][i];
}
int x = e[id][1];
int y = e[id][2];
int z = e[id][3];
int b=0,c=0;
int a=start;
if(x!=start) {
if(b==0) b=x;
else c=x;
}
if(y!=start) {
if(b==0) b=y;
else c=y;
}
if(z!=start) {
if(b==0) b=z;
else c=z;
}
if(cnt[b]==3) {
swap(b,c);
}
ans.push_back(b);
ans.push_back(c);
int m = n;
m-=3;
while (m--) {
int f=0;
for(int i=0;i<p[b].size();i++) {
for(int j=0;j<p[c].size();j++) {
if(p[b][i]==p[c][j]&&p[b][i]!=id) {
id=p[b][i];
f=id;
a=b;
b=c;
break;
}
}
if(f) break;
}
for(int i=1;i<=3;i++) {
if(e[f][i]!=a&&e[f][i]!=b) {
ans.push_back(e[f][i]);
c=e[f][i];
break;
}
}
}
for(auto e:ans) {
printf("%d ",e);
}
printf("\n");
return 0;
}