A. Perfect Permutation
题意:t组测试数据,每一次给一个n,要求输出一个1-n的全排列,要求i可以整除第i个元素ai的数量最少。
思路:,当i等于1时,i必能整除ai,可以将最大元素n放在第一个元素,剩余元素1-n-1对应放在2-n的位置上,这样后面的i无法整除ai。
代码实现:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+10;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
cout<<n;//最大元素n放在第一位
for(int i=1;i<n;i++)//1-n-1放在位置2-n上
cout<<' '<<i;
cout<<'\n';
}
return 0;
}
B. Party
题意:有一个派对,邀请n个人中部分人参加,如果第i个人没有被邀请,那么就会有不开心值ai,n个人中有m对朋友,要求被邀请的朋友的对数是偶数,求不开心值的最小值。
思路:反向思考,假设一开始所有人被邀请,观察朋友对数m当朋友对数为偶数时,那么成立,不开心值的和为0,当为奇数时,首先在记录朋友的时候同时记录每个人的度(朋友的数量),并且存储一个人的每一位朋友(像建图存边那样),,先考虑删去一个度(朋友数量)为奇数的人 ,那么肯定会去删其中不开心值最小的,然后去考虑两个度为偶数且互相为朋友的一对,如果将他们两人删去,实际上派对会少奇数个朋友,(假设一对朋友uv,他们都有偶数个朋友,u除了v之外,还剩奇数个朋友,v也如此,两点删去之后,先是出uv两点外的两组奇数个朋友删去,两个奇数的和为偶数,然后uv这对朋友也消失了,总共失去了奇数个朋友),遇上面同理,选不开心值和最小的一组。
代码实现:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int a[maxn];
int in[maxn];
int cnt=0;
int b[maxn];
vector<int>cp[maxn];
int main()
{ ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cp[i].clear();
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
cp[u].push_back(v);
cp[v].push_back(u);
}
int ans=inf;
if(m%2==0)//m为偶数的情况,可以邀请所有人
{
cout<<0<<'\n';
continue;
}
for(int i=1;i<=n;i++)
if(cp[i].size()%2==1)//寻找有奇数个朋友的人的最小不开心值
ans=min(ans,a[i]);
for(int i=1;i<=n;i++)
{
if(cp[i].size()%2==0)//寻找朋友为偶数个的人,并寻找他的朋友中也只有偶数个朋友的人
{
for(int v:cp[i])
{
if(cp[i].size()%2==0)//并寻找他的朋友中也只有偶数个朋友的人
ans=min(ans,a[i]+a[v]);
}
}
}
cout<<ans<<'\n';
}
return 0;
}
C. Color the Picture
题意:给一个n×m的矩形,有k种颜料,每种颜料有ai个,一个颜料可以涂一格方格,问是否能构建一幅美丽的画,一幅美丽的画被定义为一个方格周围至少有3个格子和他颜色相同,同时,定义第1行和 第n行,第1列和第m列是相邻的。
思路:首先,一列必须涂同一种颜色,否则就无法满足条件,其次,对于一列同一颜色,在该列两边必须至少存在与这列颜色相同的一列。否则也无法满足条件。对n行m列的网格,考虑m的奇偶性,如果偶数,那么每次选取可以涂至少两列的颜料(ai/n>=2)即可,对于奇数,每次选取(ai/2>=2)的颜料的同时,必须至少有一个(ai/2>=3)的颜料,因为如果只有“只能涂两列”的颜料,会空出一列,而单单一列不可能能满足条件。无需考虑一种颜料(ai/2>=3)占用多列而影响其他颜料的情况,因为一种颜料可以涂x列并且x>=3是,x可以任意转化成2-x列。此外,考虑网格还可以立起来,n行m列变成m行n列,也要考虑有无可能满足条件。
代码实现:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int a[maxn];
int main()
{ ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=k;i++)
cin>>a[i];
//n行m列
ll ans=0;//记录能涂多少列
bool f=0;
bool f2=0;
bool f3=0;
for(int i=1;i<=k;i++)
{
if(a[i]/n>=2)//选取能涂大于等于2列的颜料
{
if((a[i]/n)>=3)//寻找是否有能涂大于等于3列的颜料,应对列数为奇数的条件
f2=1;
ans+=(a[i]/n);
}
}
if(m%2==0)//当列数为偶数时
{
if(ans>=m)
f=1;
}
else//当列数为奇数时
{
if(ans>=m&&f2)
f=1;
}
//m行n列的情况
ans=0;
for(int i=1;i<=k;i++)
{
if(a[i]/m>=2)//选取能涂大于等于2列的颜料
{
if((a[i]/m)>=3)//寻找是否有能涂大于等于3列的颜料,应对列数为奇数的条件
f3=1;
ans+=(a[i]/m);
}
}
if(n%2==0)//当列数为偶数时
{
if(ans>=n)
f=1;
}
else
{
if(ans>=n&&f3)//当列数为奇数时
f=1;
}
if(f)
cout<<"Yes\n";
else
cout<<"No\n";
}
return 0;
}