[codeforces 1271E] Common Number 打表+找规律

[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;
}
发布了475 篇原创文章 · 获赞 509 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/mrcrack/article/details/103614420