打的第一场Atcoder,已经知道会被虐得很惨,但没有想到竟然只做出一题……
思维急需提升。
这题还是很签到的。
感觉正着做不好做,我们反着来,把加数变为删数。
显然每次有多个可以删时要删最后一个可删的,这样前面仍然合法,后面也有可能有更多合法情况。
发现不能删时就puts("-1")
。
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define sz 233
}
using namespace my_std;
int n;
vector<int>v;
int ans[sz];
int main()
{
cin>>n;
int x;
rep(i,1,n) cin>>x,v.push_back(x);
drep(i,n,1)
{
bool flg=0;
drep(j,i-1,0) if (v[j]==j+1) {flg=1;ans[i]=j+1;v.erase(v.begin()+j);break;}
if (!flg) return puts("-1"),0;
}
rep(i,1,n) printf("%d\n",ans[i]);
return 0;
}
首先手玩出n=3,4,5的情况。
观察一下图,发现\(n=3\)时\((1,2)\)未连边,\(n=4\)时\((1,4),(2,3)\)未连边,\(n=5\)时\((1,4),(2,3)\)未连边。
\(1+2=3,1+4=2+3=5\)。
猜一下结论,发现很容易证明,就做完了。
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
}
using namespace my_std;
int main()
{
int n;
cin>>n;
vector<pii>v;
rep(i,1,n) rep(j,i+1,n) if (i+j!=n+(!(n&1))) v.push_back(MP(i,j));
printf("%d\n",(int)v.size());
rep(i,0,(int)v.size()-1) printf("%d %d\n",v[i].fir,v[i].sec);
return 0;
}
CDEF还没看题解,我还是先睡觉吧。
原文:https://www.cnblogs.com/p-b-p-b/p/10586301.html