A题 每个方格破一条边即可
#include<bits/stdc++.h>
using namespace std;
int t,a,b;
int main()
{
cin>>t;
while(t--)
{
cin>>a>>b;
cout<<a*b<<'\n';
}
return 0;
}
B题 对于一对 a [ i ] < a [ i + 1 ] a[i]<a[i+1] a[i]<a[i+1], c = a [ i + 1 ] − a [ i ] + k ∗ m c=a[i+1]-a[i]+k*m c=a[i+1]−a[i]+k∗m, c c c取 a [ i + 1 ] − a [ i ] a[i+1]-a[i] a[i+1]−a[i]即可,因为在模 m m m的情况下一样, c c c一旦确定, m m m也可以确定,只要判断这对 c , m c,m c,m能不能推出整个序列即可
我代码写的太繁琐了就不放了 (比赛时把所有情况都写进去了,会有重复判断的部分)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,a[N];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int m,ma=0,c;
bool f=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]),ma=max(ma,a[i]);
if(n==1||n==2)
{
puts("0");
continue;
}
for(int i=2;i<=n;i++)
{
if(a[i]!=a[i-1])f=1;
}
if(!f)
{
puts("0");
continue;
}
f=0;
for(int i=1;i<n;i++)
{
if(a[i]>=a[i+1])f=1;
}
if(!f)
{
bool ff=0;
for(int i=1;i<n-1;i++)
{
if(a[i+1]-a[i]!=a[i+2]-a[i+1])
{
ff=1;
break;
}
}
if(ff)puts("-1");
else puts("0");
continue;
}
f=0;
for(int i=1;i<n;i++)
{
if(a[i]<=a[i+1])f=1;
}
if(!f)
{
if(!f)
{
bool ff=0;
for(int i=1;i<n-1;i++)
{
if(a[i+1]-a[i]!=a[i+2]-a[i+1])
{
ff=1;
break;
}
}
if(ff)puts("-1");
else puts("0");
continue;
}
}
f=0;
for(int i=1;i<n;i++)
{
if(a[i]==a[i+1])f=1;
}
if(f)
{
puts("-1");
continue;
}
for(int i=1;i<n;i++)
{
if(a[i]<a[i+1])
{
c=a[i+1]-a[i];
break;
}
}
f=0;
if(c==-1)
{
puts("-1");
continue;
}
for(int i=1;i<n;i++)
{
if(a[i]<a[i+1]&&a[i+1]-a[i]!=c)
{
f=1;
break;
}
}
if(f)
{
puts("-1");
continue;
}
for(int i=1;i<n;i++)
{
if(a[i]>a[i+1])
{
m=a[i]+c-a[i+1];
break;
}
}
for(int i=1;i<n;i++)
{
if(a[i]>a[i+1]&&a[i]+c-a[i+1]!=m)
{
f=1;
break;
}
}
if(f)
{
puts("-1");
continue;
}
if(ma>=m)puts("-1");
else cout<<m<<' '<<c%m<<'\n';
}
return 0;
}
C题 只要 k = 1 k=1 k=1的情况下的 m a x ( c n t [ x ] ) < = ( m + 1 ) / 2 max(cnt[x])<=(m+1)/2 max(cnt[x])<=(m+1)/2就有解.
举个例子(不表示出k)(最坏的情况下)
2
2
2
2
1 2
1 2
1 2
显然前面4天选2,后面3天选1即可
要先把 k = 1 k=1 k=1的情况固定,在去看k>1的情况;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,k[N],cnt[N],ans[N];
vector<int>v[N];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(cnt,0,sizeof cnt);
int mm=0;
for(int i=1;i<=m;i++)v[i].clear();
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&k[i]);
for(int j=1;j<=k[i];j++)
{
scanf("%d",&x);
v[i].push_back(x);
}
if(k[i]==1)
{
cnt[x]++;
if(mm<=cnt[x])mm=cnt[x];
}
}
if(mm>(m+1)/2)
{
puts("NO");
continue;
}
puts("YES");
for(int i=1;i<=m;i++)
{
if(k[i]==1)ans[i]=v[i][0];
else
{
for(int j=0;j<k[i];j++)
if(cnt[v[i][j]]+1<=(m+1)/2)
{
cnt[v[i][j]]++;
ans[i]=v[i][j];
break;
}
}
}
for(int i=1;i<=m;i++)cout<<ans[i]<<' ';
puts("");
}
return 0;
}
D题 n e [ i ] ne[i] ne[i]用来表示 i i i这个位置的下一个未被删除的元素的下标, a n s ans ans存答案,先把原数组相邻2个 g c d gcd gcd为1的2个下标存入q中,比如一个 ( x , y ) (x,y) (x,y),然后把y删了之后再判断 a [ x ] a[x] a[x]与 a [ n e [ y ] ] a[ne[y]] a[ne[y]]的 g c d gcd gcd如果是1,就把 ( x , n e [ y ] ) (x,ne[y]) (x,ne[y])存入q中,循环
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int t,n,a[N];
map<int,int>ne;
queue<pair<int,int>>q;
vector<int>ans;
int gcd(int a,int b){
int r;
while(b)
{
r=a%b;
a=b;
b=r;
}
return a;
}
int main()
{
scanf("%d",&t);
while(t--)
{
ans.clear();
ne.clear();
while(q.size())q.pop();
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
ne[i]=i+1;
if(gcd(a[i],a[i+1])==1)
q.push({
i,i+1});
}
ne[n]=1;
if(gcd(a[n],a[1])==1)q.push({
n,1});
while(q.size())
{
auto now=q.front();
q.pop();
int x=now.first,y=now.second;
if(!ne.count(x))continue;
ans.push_back(y);
ne[x]=ne[y];
if(gcd(a[x],a[ne[x]])==1)
q.push({
x,ne[x]});
ne.erase(y);//一定要先判断再删,不然会出现ne为空的情况
}
cout<<ans.size()<<' ';
for(int i=0;i<ans.size();i++)cout<<ans[i]<<' ';
puts("");
}
return 0;
}