题解:P11890 [XRCOI Round 1] A. 相聚相逢本无意
Pyrf_uqcat · · 题解
赛时搞了好久,做法是将每个子任务逐个击破。
子任务一
子任务说明
无需考虑太多,当有
可以拿下子任务一得到三十分。
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,ans[N]={-1},k;
struct Node
{
int x,y;
}a[N];
bool flag[N];
map<int,int> mp;
bool cmp(Node x,Node y)
{
return x.x<y.x;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
for(int j=ans[k]+1;j<a[i].x-1;j++)
{
ans[++k]=j;
}
while(a[i].y--) ans[++k]=a[i].x-1;
if(k>2e5) cout<<-1<<endl,exit(0);
}
cout<<k<<endl;
for(int i=1;i<=k;i++)
{
cout<<ans[i]<<' ';
}
cout<<endl;
return 0;
}
子任务二
现在
当
通过子任务二拿到六十分。
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,ans[N]={-1},k,flagg;
struct Node
{
int x,y;
}a[N];
bool flag[N];
map<int,int> mp;
bool cmp(Node x,Node y)
{
return x.x<y.x;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(flagg&&a[i].y) cout<<-1<<endl,exit(0);
if(a[i].y==0)
{
flagg=1;
continue;
}
for(int j=ans[k]+1;j<a[i].x-1;j++)
{
ans[++k]=j;
}
while(a[i].y--) ans[++k]=a[i].x-1;
if(k>2e5) cout<<-1<<endl,exit(0);
}
cout<<k<<endl;
for(int i=1;i<=k;i++)
{
cout<<ans[i]<<' ';
}
cout<<endl;
return 0;
}
子任务三
当要出现
拿下子任务三得到九十分。
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,ans[N]={-1},k,flagg,flaggg;
struct Node
{
int x,y;
}a[N];
bool flag[N];
map<int,int> mp;
bool cmp(Node x,Node y)
{
return x.x<y.x;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(flagg&&a[i].y) cout<<-1<<endl,exit(0);
if(flaggg&&a[i].y) cout<<-1<<endl,exit(0);
if(a[i].y==0)
{
flagg=1;
continue;
}
if(a[i].x==0)
{
flaggg=1;
continue;
}
for(int j=ans[k]+1;j<a[i].x-1;j++)
{
ans[++k]=j;
}
while(a[i].y--) ans[++k]=a[i].x-1;
if(k>2e5) cout<<-1<<endl,exit(0);
}
if(flaggg)
{
cout<<a[1].y<<endl;
for(int i=1;i<=a[i].y;i++)
{
cout<<1<<' ';
}
cout<<endl;
return 0;
}
cout<<k<<endl;
for(int i=1;i<=k;i++)
{
cout<<ans[i]<<' ';
}
cout<<endl;
return 0;
}
子任务四
经过前三个子任务但还是有几个点没过,这是因为漏了一个特殊的样例。当
赛时通过代码
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (a)<(b)?(a):(b)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,ans[N]={-1},k,flagg,flaggg;
struct Node
{
int x,y;
}a[N];
bool flag[N];
map<int,int> mp;
bool cmp(Node x,Node y)
{
return x.x<y.x;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(a[i].x==0&&a[i].y==0) continue;
if(flagg&&a[i].y) cout<<-1<<endl,exit(0);
if(flaggg&&a[i].y) cout<<-1<<endl,exit(0);
if(a[i].y==0)
{
flagg=1;
continue;
}
if(a[i].x==0)
{
flaggg=1;
continue;
}
for(int j=ans[k]+1;j<a[i].x-1;j++)
{
ans[++k]=j;
}
while(a[i].y--) ans[++k]=a[i].x-1;
if(k>2e5) cout<<-1<<endl,exit(0);
}
if(flaggg)
{
cout<<a[1].y<<endl;
for(int i=1;i<=a[i].y;i++)
{
cout<<1<<' ';
}
cout<<endl;
return 0;
}
cout<<k<<endl;
for(int i=1;i<=k;i++)
{
cout<<ans[i]<<' ';
}
cout<<endl;
return 0;
}
题外:
这辈子写过最长的题解,四千多字符,同时也是写过的最复杂的方法。其实应该是可以直接推得结果的,但是赛时搞了好久每个子任务都错了一两个,只能使用这么不聪明的方法了。