[codeforces 1271E] Common Number 打表+找规律
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址http://codeforces.com/contest/1271/problem/E
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
E - Common Number | GNU C++11 | Accepted | 31 ms | 0 KB |
打表代码如下
#include <stdio.h>
#define maxn 110
int c[maxn],tot;
void f(int x){
int i;
c[x]++;
if(x==1){
for(i=1;i<=tot;i++)printf("%3d",c[i]);
printf("\n");
return ;
}
if(x%2==0)f(x/2);
else f(x-1);
}
int main(){
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++){
tot=i;
f(i);
}
for(i=1;i<=n;i++)printf("%3d",i);
printf("\n");
return 0;
}
打表数据如下
AC代码如下
思考过程如下
//提交,Wrong answer on test 10 。
//看数据,加读题,发现,int溢出,要用long long
//在将int修改成long long过程中,不断遇到问题,跟踪了数据,问题得以解决。
//提交AC.2019-12-19
//独立编写完成该题,信心得到极大增强,当时就基本判定该题的算法要么O(logn)要么能找到具体公式。
//编写过程中,逐一得到验证。
#include <stdio.h>
#define LL long long
struct node{
LL ln,lv;//左边界,ln对应个数,lv具体数字
LL rn,rv;//右边界,rn对应个数,rv具体数字
LL n[6],v[6];//逆序的4个数
}a[100];
int tot=0;
LL n,k,b;
int main(){
int i,j,check;//此处错写成int i,cmd,j,check;
LL cmd;
scanf("%lld%lld",&n,&k),b=1;
for(i=1;;i++){
if(n==0)break;
a[i].rv=n,a[i].rn=a[i-1].ln*(a[i-1].lv%2)+1;//当前对应个数=相邻的个数+2倍数字对应的个数+自己1
for(j=1;j<=4;j++)
if(a[i].rv*2==a[i-1].v[j])break;
a[i].rn+=a[i-1].n[j];//此处错写成a[i].rn+=a[i-1].v[j];
a[i].lv=n/2+1;
cmd=a[i].rv-a[i].lv+1;
if(cmd>=4){
a[i].n[1]=a[i].rn,a[i].v[1]=a[i].rv;
for(j=2;j<=4;j++)a[i].v[j]=a[i].v[j-1]-1;
for(j=1;j<=4;j++)
if(a[i].v[2]*2==a[i-1].v[j])break;
a[i].n[2]=a[i-1].n[j]+a[i].n[1]*(a[i].v[1]%2)+1;//此处错写成a[i].n[2]=a[i-1].n[j]+a[i].n[1]*(a[i].n[1]%2);
a[i].n[3]=b+b*((a[i].v[3]-1)%2);//a[i].n[3]=(2*(i-1)+1)+(2*(i-1)+1)*((a[i].v[3]-1)%2);
a[i].n[4]=b+b*((a[i].v[4]-1)%2);//a[i].n[4]=(2*(i-1)+1)+(2*(i-1)+1)*((a[i].v[4]-1)%2);
a[i].ln=b+b*((a[i].lv-1)%2);//a[i].ln=(2*(i-1)+1)+(2*(i-1)+1)*((a[i].lv-1)%2);
}else if(cmd==3){
a[i].n[1]=a[i].rn,a[i].v[1]=a[i].rv;
for(j=2;j<=3;j++)a[i].v[j]=a[i].v[j-1]-1;
a[i].lv=a[i].v[4]=a[i].v[3];
for(j=1;j<=4;j++)
if(a[i].v[2]*2==a[i-1].v[j])break;
a[i].n[2]=a[i-1].n[j]+a[i].n[1]*(a[i].v[1]%2)+1;//此处错写成a[i].n[2]=a[i-1].n[j]+a[i].n[1]*(a[i].n[1]%2)+1;//此处错写成a[i].n[2]=a[i-1].n[j]+a[i].n[1]*(a[i].n[1]%2);
a[i].n[3]=b+b*((a[i].v[3]-1)%2);//a[i].n[3]=(2*(i-1)+1)+(2*(i-1)+1)*((a[i].v[3]-1)%2);
a[i].ln=a[i].n[4]=a[i].n[3];
}else if(cmd==2){
a[i].n[1]=a[i].rn,a[i].v[1]=a[i].rv;
for(j=2;j<=4;j++)a[i].v[j]=a[i].rv-1;
for(j=1;j<=4;j++)
if(a[i].v[2]*2==a[i-1].v[j])break;
a[i].n[2]=a[i-1].n[j]+a[i].n[1]*(a[i].v[1]%2)+1;//此处错写成a[i].n[2]=a[i-1].n[j]+a[i].n[1]*((a[i].v[1]-1)%2)+1;//此处错写成a[i].n[2]=a[i-1].n[j]+a[i].n[1]*((a[i].n[1]-1)%2)+1;//此处错写成a[i].n[2]=a[i-1].n[j]+a[i].n[1]*(a[i].n[1]%2)+1;
for(j=3;j<=4;j++)a[i].n[j]=a[i].n[2];
a[i].ln=a[i].n[2];
}else if(cmd==1){
for(j=1;j<=4;j++)a[i].n[j]=a[i].rn,a[i].v[j]=a[i].rv;
a[i].ln=a[i].rn;
}
n/=2,tot++;
b=b*2+1;
}
/*for(i=1;i<=tot;i++){//打印分块
printf("rv=%lld rn=%lld lv=%lld ln=%lld\n",a[i].rv,a[i].rn,a[i].lv,a[i].ln);
for(j=1;j<=4;j++)printf("v[%d]=%lld n[%d]=%lld\n",j,a[i].v[j],j,a[i].n[j]);
printf("\n");
}*/
check=0;
for(i=1;i<=tot;i++){//此处错写成for(i=1;i<tot;i++){
for(j=1;j<=4;j++)
if(a[i].n[j]>=k){check=1;break;}
if(check)break;
}
printf("%lld\n",a[i].v[j]);
return 0;
}