A题 把从小到大排序再把重复的排到后面
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[110];
int main()
{
scanf("%d",&t);
while(t--)
{
memset(cnt,0,sizeof cnt);
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),cnt[a[i]]++;
int c=0;
while(c<n)
{
for(int i=0;i<=100;i++)
{
if(cnt[i]>0)
{
cout<<i<<' ';
cnt[i]--;
c++;
}
}
}
puts("");
}
return 0;
}
B题 把 a [ i ] a[i] a[i]% m m m,枚举 a [ i ] a[i] a[i],看有没有 a [ j ] = m − a [ i ] a[j]=m-a[i] a[j]=m−a[i]
比如 m = 5 , a [ i ] = 2 m=5, a[i]=2 m=5,a[i]=2,看下存不存在 3 3 3
可以 2 3 2 3 2 3…组成一个序列
需特判下 a [ i ] = 0 a[i]=0 a[i]=0和 m m m% 2 = = 0 2==0 2==0的情况,把 0 0 0和 m / 2 m/2 m/2的分别全部分成一组
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[N];
int main()
{
scanf("%d",&t);
while(t--)
{
memset(cnt,0,sizeof cnt);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),a[i]=a[i]%m,cnt[a[i]]++;
int ans=0;
if(m%2==0&&cnt[m>>1])ans++,cnt[m>>1]=0;
if(cnt[0])ans++,cnt[0]=0;
for(int i=1;i<=n;i++)
{
int x=a[i];
if(cnt[m-x]&&cnt[x])
{
ans++;
if(cnt[x]>cnt[m-x])
{
int mm=cnt[m-x];
cnt[m-x]=0,cnt[x]-=mm+1;
}
else if(cnt[x]<cnt[m-x])
{
int mm=cnt[x];
cnt[m-x]-=mm+1,cnt[x]=0;
}
else cnt[x]=cnt[m-x]=0;
}
}
for(int i=0;i<m;i++)ans+=cnt[i];
cout<<ans<<'\n';
}
return 0;
}
C1题 找规律
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[N];
int main()
{
scanf("%d",&t);
while(t--)
{
int n,k;
cin>>n>>k;
if((n-1)%2==0)cout<<1<<' '<<(n-1)/2<<' '<<(n-1)/2<<'\n';
else if(n%3==0)cout<<n/3<<' '<<n/3<<' '<<n/3<<'\n';
else if(((n-2)/2)&1)cout<<n/4<<' '<<n/4<<' '<<n/2<<'\n';
else cout<<2<<' '<<(n-2)/2<<' '<<(n-2)/2<<'\n';
}
return 0;
}
C2题 每次输出1,再 n n n- -, k k k- -,直到 k = 3 k=3 k=3,然后和C1一样的做法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,m,a[N],cnt[N];
int main()
{
scanf("%d",&t);
while(t--)
{
int n,k;
cin>>n>>k;
while(k>3)
{
n--,k--;
cout<<1<<' ';
}
if((n-1)%2==0)cout<<1<<' '<<(n-1)/2<<' '<<(n-1)/2<<'\n';
else if(n%3==0)cout<<n/3<<' '<<n/3<<' '<<n/3<<'\n';
else if(((n-2)/2)&1)cout<<n/4<<' '<<n/4<<' '<<n/2<<'\n';
else cout<<2<<' '<<(n-2)/2<<' '<<(n-2)/2<<'\n';
}
return 0;
}
E1题 分解质因数,令 a [ i ] = p 1 k 1 + p 2 k 2 + . . . + p t k t a[i]=p_1 ^{k_1}+p_2 ^{k_2}+...+p_t ^{k_t} a[i]=p1k1+p2k2+...+ptkt
再把偶次幂的去掉就行了,
比如样例 18 6 2 4 1
把偶次幂去掉后 2 6 2 0 0
遍历一遍,如果这个数在前面出现过,那么 a n s + + , m p ans++,mp ans++,mp清空, m p mp mp再把当前值存下
记得线性筛,不然会T
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int t,n,k,a[N],prim[N];;
unordered_map<int,bool>mp;
bool vis[N];
void init(){
int cnt=0;
for(int i=2;i<=10000;++i)
{
if(!vis[i])prim[++cnt]=i;
for(int j=1;prim[j]<=10000/i;++j)
{
vis[i*prim[j]]=1;
if(i%prim[j]==0)break;
}
}
}
int main()
{
scanf("%d",&t);
init();
while(t--)
{
mp.clear();
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
int x;
a[i]=1;
scanf("%d",&x);
for(int j=1;prim[j]<=x/prim[j];j++)
{
int cnt=0;
while(x%prim[j]==0)x/=prim[j],cnt++;
if(cnt&1)a[i]*=prim[j];
}
if(x>1)a[i]*=x;
}
int ans=0;
mp[a[1]]=1;
for(int i=2;i<=n;i++)
{
if(mp.count(a[i]))
{
ans++;
mp.clear();
}
mp[a[i]]=1;
}
if(mp.count(a[n]))ans++;
cout<<ans<<'\n';
}
return 0;
}