题意:
A(CodeForces - 1249 C1&C2):找一个最小的大于n的数,要求是3的幂次和且每个次数最多出现一次。
B(CodeForces - 1249A )一组数,如果有两数之差为一,把他们放在两个不同的组里。
C(CodeForces - 1249 D1&D2):给多组线段,每一个点的覆盖次数不超过K,每次可去除一个线段,问最少去多少线段以及线段的位置。
D(CodeForces - 1249 B1&B2):数组a[n],每过一天书会从i转到a[i],问多少天回到最开始的人手里。
题解:
A&E CodeForces - 1249 C1&C2 Good Numbers
思路:1、通过判断n%3=2,2=3的0次方+3的0次方所以只要n%3=2就不符合要求
2、利用三进制所以,对于位为0、1的情况不处理,只对位为2的处理,处理成“3”,也就是本位记0,然后进位给下一位。所以每次获取的新本位是由原本位和进位决定的。这样处理完之后,得到的结果是可能偏大的,因为可能高位就已经保证了整个数是大于等于n的,所以多余的低位会让结果更大,所以要比较每一个的新位与原位,如果它们相等,那么这一位就是必须的,最后转换回十进制。
代码:
1、
#include<bits/stdc++.h>
int q,sum,m,n;
using namespace std;
int main()
{
int q;
cin>>q;
while (q--)
{
cin>>m;
n = m;
sum = 0;
while (1)
{
bool f = true;
while (n > 0)
{
if (n % 3 == 2)
{
f = false;
break;
}
n = n / 3;
}
if (f == true)
{
cout<<m+sum<<endl;
break;
}
else
{
++sum;
n = m + sum;
}
}
}
}
2、
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int M = 60;
int bit[M], abit[M], cnt;
long long pow3[M];
int main() {
pow3[0] = 1;
for (int i = 1; i < M; i++) pow3[i] = pow3[i - 1] * 3;
ll t, n, m, carry, temp, ans;
cin >> t;
while (t--) {
cin >> n;
m = n;
carry = 0;
for (cnt = 0; m; cnt++) {
bit[cnt] = m % 3;
temp = bit[cnt] + carry;
if (temp == 0) abit[cnt] = 0;
else if (temp == 1) abit[cnt] = 1, carry = 0;
else if (temp >= 2) abit[cnt] = 0, carry = 1;
m /= 3;
}
if (carry) {
bit[cnt] = 0;
abit[cnt] = 1;
cnt++;
}
cnt--;
ans = 0;
while (cnt >= 0) {
if (abit[cnt] > bit[cnt]) {//1,0
ans += pow3[cnt];
break;
}
else if (abit[cnt] == bit[cnt]) ans += abit[cnt] * pow3[cnt];
cnt--;
}
cout << ans << endl;
}
return 0;
}
G CodeForces - 1249 B2 Books Exchange (hard version)(队列)
思路:用队列来储存变换的
代码:
#include<bits/stdc++.h>
using namespace std;
int t,n;
int a[220000],b[220000];
int main()
{
cin>>t;
while(t--)
{
cin>>n;
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
queue<int>q;
for(int i=1;i<=n;i++)
{
if(b[i])
continue;
int m=i;
do
{
q.push(m);
m=a[m];
}while(m!=i);
int ans=q.size();
while(!q.empty())
{
b[q.front()]=ans;
q.pop();
}
}
for(int i=1;i<n;i++)
cout<<b[i]<<' ' ;
cout<<b[n]<<endl;
}
return 0;
}
感想:感觉状态多多少少回来一点了。A想打表来着,WA之后发现要打两次,想想还是算了,就换了种思路。D题就毫无思路,B2的话是真的没往队列上靠,知识点的应用能力还是差太多,明天把学过的都列出来,弄个思维导图。