sgu——169、178

题目地址:

http://acm.sgu.ru/submit.php?problem=169

http://acm.sgu.ru/submit.php?problem=178

169解析:因为n和n+1相邻,因此两者的P(n)必然也相邻,且为一位数,则要求n的前导必然为1,只有最后一位可以变动,现在讨论最后一位。(结尾为1、2、5的时候,p(n)显然满足,作为已知)为1的时候必然成立,为2的时候只有当尾数为3的数整除3,则要求前面1的个数是3的倍数。为5的时候成立则要求为6的数整除6,测试发现前导有3的倍数个1的时候一直为1、5、3循环,则36必然整除6.(要求前导有3个倍数个1)。当6成立的时候,则要求尾数为7可以整除7,测试发现前导有6个倍数个1的时候为1、4、6、5、2、0,显然最后一位的7可以整除7,因此当6成立的时候前导有6个倍数个1.(不得不感叹数字真的太奇妙了)

#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
#define INF 0xfffffff
#define MAX(a,b) a>b?a:b
#define MIN(a,b) a>b?b:a
int main()
{
	int i,j,k,t;
	int m,n;
    while(cin>>k)
    {
    	if(k==1) cout<<"8"<<endl;
    	else if((k-1)%3) cout<<"1"<<endl;
    	else
    	 {
	    	if((k-1)%2==0) cout<<"4"<<endl;
	    	else cout<<"3"<<endl;
	 }    	
    }
	return 0;
}

178解析:破坏X个会产生至少X个1,会产生X+1~2X+1块,显然产生的块数越大,所组成的可能性越大,破坏X个达到的范围也就越大。因此直接考虑产生2X+1块(包括已有的X个1)的情况。X个1能组成1~X中间的任意数,这是显然,因此需要在X+1处有个值,(不然不满足条件),则加上X+1这个值之后显然可以组成X+1~2X+1之间的值,则需要在2X+2处有个值,可以组成2X+2~2(2X+2)-1之间的值,依次类推,最后在后面加上X+1个数,则表示的区间为X*2^X(这个又是上个(X-1)表示的最大值加1)到(X+1)*2^(X+1)-1.

#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
#define INF ((ll)1<<59)
#define MAX(a,b) a>b?a:b
#define MIN(a,b) a>b?b:a
#define M 50
struct N
{
	ll st,ed;   //记录必须破坏x个的开始N值,以及破坏x个达到的最大的值。
}a[M];
ll f[M];
void init()
{ 
    a[1].st=1;
    int j;
	for(int i=1;i<M-1;i++)
	{
		f[0]=i+1;
		for(j=1;j<=i;j++)
		  {
		  ll temp=f[j-1]*2;
		  if(temp>INF) break;//大于要求的值之后直接跳出。
		  else f[j]=temp;
		  }
		 a[i].ed=2*f[j-1]-1;
	         a[i+1].st=a[i].ed+1;
	}
}
int search(ll n)    //查找在那个区间里。
{
	for(int i=1;i<M;i++)
	   if(n>=a[i].st&&n<=a[i].ed) return i;
}
int main()
{
	int i,j,k,t;
	ll m,n;
	init();
	while(cin>>n)
	{
		if(n==1) cout<<"0"<<endl;
		else cout<<search(n)<<endl;
	}
	return 0;
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值