思路:
先构造一个数组s[i],s[i]表示i个1能“构造”出几个1。
然后就分别枚举1的个数和-1的个数
例如
假如有3个位置
1为0个,-1 为 3个
1为1个,-1 为 2个
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#define endl "\n"
using namespace std;
const int N=110;
int s[N];
void solve(){
int n,k;
cin>>n>>k;
int cnt_1=0;
int cnt_2=0;
int res=0;
int x=n;
int flag=0;
while(n){
cnt_1=n;
cnt_2=x-cnt_1;
res=s[cnt_1]+s[cnt_2];
if(res==k){
flag=1;
break;
}
n--;
}
if(flag){
puts("YES");
for(int i=1;i<=cnt_1;i++){
cout<<1<<' ';
}
for(int i=1;i<=cnt_2;i++){
cout<<-1<<' ';
}cout<<endl;
}else {
puts("NO");
}
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
for(int i=2;i<=110;i++){
s[i]=s[i-1]+i-1;
}
int T;
cin>>T;
while(T--){
solve();
}
return 0;
}
B
思路:
对于每个数字判断他此时的位置和他应该所在的位置之差的绝对值是否是k的倍数
abs(a[i]-i)%k==0
若是则可以自己交换让他回到正确的位置
否则cnt++
当cnt>2时,输出-1。因为此时表示不合理的位置>2个,就表明通过一次特殊交换还剩一些数字。
当cnt为2时,判断这两个数字交换后是否合理,若合理输出1,否则输出-1
当cnt = 0时,输出0
不存在cnt=1的情况
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#define endl "\n"
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10;
int a[N];
void solve()
{
int n,k;
cin>>n>>k;
int cnt=0;
vector<PII> b;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
if( abs(a[i]-i)%k==0 ) continue;
else
{
cnt++;
b.push_back({i,a[i]});
}
}
if(cnt>2) cout<<-1<<endl;
else if(cnt==0) cout<<0<<endl;
else if(cnt==2)
{
swap(b[0].first,b[1].first);
if( (b[0].second-b[0].first) % k ==0 &&(b[1].second-b[1].first)%k ==0)
{
cout<<1<<endl;
}else cout<<-1<<endl;
}
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
其实只要cnt==2就输出1就好了~
赛时就是这么想的,但不知道代码哪里出问题了。。。。
#include<iostream>
#include<cstring>
#include<algorithm>
#define endl "\n"
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10;
int a[N];
void solve()
{
int n,k;
cin>>n>>k;
int cnt=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
if( abs(a[i]-i)%k!=0 ) cnt++;
}
if(cnt==0) cout<<0<<endl;
else if(cnt>2) cout<<-1<<endl;
else if(cnt==2) cout<<1<<endl;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
若q 为质数,则qq为强合数
若p,q,r为质数,则pq*r 为强合数
思路:
对a[i]分解质因数
我们现在要让b数组的长度最长
则就应该先枚举个数为2的质因数,再用3个不同的质因数组成一组(如果找不到)就把当前剩下的质因数乘到已经找到的答案中
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#define endl "\n"
using namespace std;
const int N=1e3+10;
int a[N];
void solve()
{
int n;
cin>>n;
map<int,int> mp;
for(int i=1;i<=n;i++)//对于每一个数分解质因数
{
cin>>a[i];
for(int j=2;j<=a[i]/j;j++)
{
if(a[i]%j==0)
{
while(a[i]%j==0)
{
mp[j]++;//质数j的个数++
a[i]/=j;
}
}
}
if(a[i]>1) mp[a[i]]++;
}
int res=0;
int cnt=0;
for( auto item : mp)
{
res+=item.second/2;
cnt+=item.second%2;
}
res+=cnt/3;
cout<<res<<endl;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}