A
题意:给你n个数,可以把他们分组,相差只为1的数不能分为一组,问能分几组
思路:最多能分两组,只要存在两个数相差为一就要分两组否则就是一组
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 105;
int arr[MAXN];
int main()
{
int T;
cin>> T;
while(T--)
{
int n;
cin >> n;
for(int i=0;i<n;i++) cin >> arr[i];
sort(arr,arr+n);
int num=0,ans=1;
for(int i=0;i<n-1;i++)
{
if(arr[i+1]-arr[i]==1)
ans=2;
}
cout<<ans<<endl;
}
return 0;
}
B1
题意:从1到n,第i个数ai表示他结束后传给第ai个数,问你每个i多长时间能再传回自己
思路:每个i都有自己的循环,找到每个i在哪个循环里就行了,用栈保存每一个循环,找出他的大小。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
const int maxn = 2e5+100;
int vis[maxn];
int ans[maxn];
int a[maxn];
stack<int>s;
int main()
{
int t,n,x,day;
int i,j;
cin >> t;
while(t--)
{
cin >> n;
memset(a,0,sizeof(a));
memset(vis,-1,sizeof(vis));
memset(ans,0,sizeof(ans));
for(i=1;i<=n;i++)
cin >> a[i];
for(i=1;i<=n;i++)
{
day=0;
if(vis[i]!=-1) continue;
x=a[i];
while(x!=i)
{
s.push(x);
x = a[x];
}
s.push(x);
day = s.size();
while(!s.empty())
{
x=s.top();
s.pop();
ans[x] = day;
vis[x] = 1;
}
}
for(int i=1;i<=n;i++)
cout <<ans[i]<<" ";
cout <<endl;
}
}
C:
题意:给你一个数,让你求大于等于他的最小good number
goodnumber 就是 由不同的3的次方加起来得到的数
思路:把他先转化为3进制的数,用一个数组保存,因为每个3的n次方只能加一次,所以某个位上如果是2那就是不行的,解决方法就是找到最大位上的2,然后从他再开始找0,把他之后的第一个0变成1。
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
ll bit[100];
ll quickpow(ll n, ll m){
ll ans = 1;
while(m){
if(m&1) ans *= n;
n*=n;
m>>=1;
}
return ans;
}
int main(){
int q;
scanf("%d",&q);
while(q--){
ll n, nn, sum=0;
memset(bit, 0, sizeof(bit));
scanf("%I64d",&n);
nn=n;
ll tot=0;
while(n) bit[++tot]=n%3, n/=3;
ll i;
for(i=tot; i>=1; i--)
if(bit[i]==2) break;
if(!i) printf("%I64d\n", nn);
else{
for(i++;;i++)
if(bit[i]==0 || i>tot) {
bit[i]=1;
break;
}
if(i>tot) sum=quickpow(3, i-1);
for(;i<=tot;i++) if(bit[i]==1) sum+=quickpow(3, i-1);
printf("%I64d\n",sum);
}
}
return 0;
}