思维专题(未完待续)

1.斐波那契数列的应用:

斐波那契数列里面任意三个都不能构成三角形

例题:一段长为n的绳子切成m段,问最多能切多少段使得任意三条边都构不成三角形。

#include<stdio.h>
#include<string.h>
#define max 1000+10
int a[max];
int main()
{
    int t,n,i,j,sum;
    a[1]=a[2]=1;
    for(i=3;i<max;i++)
    {
        a[i]=a[i-1]+a[i-2];
    }
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        sum=0;
        for(i=1;i<max;i++)
        {
            sum+=a[i];
            if(sum>=n)
            break;
        }
        if(sum==n)
        printf("%d\n",i);
        else
        printf("%d\n",i-1);
    } 
    return 0;
}

2.humble Numbers

题意:一个数的prime因子仅在2,3,5,7几个数中,则成为humble Number。求第n个humber Number

代码:

#include<stdio.h>
#include<string.h>
#define max 5843
int humble[max];
int min(int x,int y)
{
    return x<y?x:y;
}
int main()
{
    int n,i,j,k;
    int a2,a3,a5,a7;
    int p2,p3,p5,p7;
    humble[1]=1;p2=p3=p5=p7=1;
    for(i=2;i<max;i++)
    {
        a2=humble[p2]*2;
        a3=humble[p3]*3;
        a5=humble[p5]*5;
        a7=humble[p7]*7;
        humble[i]=min(min(a2,a3),min(a5,a7));
        if(humble[i]==a2)
        {
            p2++;
        }
        if(humble[i]==a3)
        {
            p3++;
        }
        if(humble[i]==a5)
        {
            p5++;
        }
        if(humble[i]==a7)
        {
            p7++;
        }
    }
    while(scanf("%d",&n)&&(n!=0))
    {
        k=n%100;//最后两位 
        if(k>=10&&k<=20)
        {
            printf("The %dth humble number is %d.\n",n,humble[n]);
            continue;
        }
        k=n%10;
        printf("The %d",n);
        if(k==1)
        printf("st ");
        else if(k==2)
        printf("nd ");
        else if(k==3)
        printf("rd ");
        else
        printf("th ");
        printf("humble number is %d.\n",humble[n]);
    }
    return 0;
}

3.输出  N!%2009

思路:因为2009=41*7*7

所以41!一定是2009的倍数,所以大于41的话阶乘2009的倍数~mod后结果是0

4.有一串连续的数字1~n,之后打乱其顺序,只能将后面的数字提到最前面,问至少需要几步

思路:从最大的数开始往前找递减序列,用n减去其长度就好~

5.给两个数  N 和 M ,然后每次操作——N可以乘上他的一个因子变成一个新的数,问N是否有可能经过一系列变换变成M。

可能的话输出操作次数。

思路:每次乘gcd(N,M),然后判断一下新数字与M是否互质或者新数字大于M,满足的话break;

注意M<=2^63,所以不能用long long或者__int 64,只能用 unsigned long long.

6.LightOJ1010---Knight in Chessboard

题意:马走日。给定一个n*m的棋盘,问最多能放多少个马。由于给定的t很大,所以就是找规律的题

思路:

①:如果n*m是偶数,&& n>2  &&  m>2

答案是:n*m/2;

②:如果是n和m都是奇数 && n>2 && m>2

答案是一半的行放  m/2+1 个,另一半放  m/2个

③:如果n,m都小于等于2

n(m)为1,答案就是m(n)

④:m(n)有一个为2,那么我们可以考虑可以分出多少个2*2的格子 
设有x个,答案是(x/2+x(x/2+x % 2)42)∗4 
剩下来可能有一个2*1的,这时如果x是奇数,不能放,如果x是偶数可以放

代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t, icase = 1;
    scanf("%d", &t);
    while (t--) {
        int n, m;
        scanf("%d%d", &n, &m);
        int ans = 0;
        if (n >= 3 && m >= 3) {
            if (n * m % 2 == 0) {
                ans = n * m / 2;
            }
            else {
                int s = m / 2 + 1;
                ans += (n / 2 + 1) * s;
                ans += (n / 2) * (s - 1);
            }
        }
        else {
            if (n == 1) {
                ans = m;
            }
            else if (m == 1) {
                ans = n;
            }
            else {
                if (m == 2) {
                    swap(n, m);
                }
                if (m <= 3) {
                    ans = 4;
                }
                else {
                    int cnt = m / 2;
                    ans = (cnt / 2 + cnt % 2) * 4;
                    if (m % 2 && cnt % 2 == 0) {
                        ans += 2;
                    }
                }
            }
        }
        printf("Case %d: %d\n", icase++, ans);
    }
    return 0;
}

7.lightoj 1349 - Aladdin and the Optimal Invitation (中位数的运用)

题目大意:题目是让找到一个点,使得其他点到这个点的曼哈顿距离最小,给出n*m的表格,p个位置各有w人,问在那个坐标集合使所有人走得距离最小,
思路:算出总人数,x y排序,位于中位数的那个人的xy 坐标

代码:

#include<cstdio>
#include<algorithm>
#include<cstring> 
using namespace std;
struct T
{
	int x,y,w;	
}a[50010];
bool cmp1(T u,T v)
{
	return u.x<v.x;//
}
bool cmp2(T u,T v)//
{
	return u.y<v.y;
}
int main()
{
	int t,n,m,q,k=1;
	int xx,yy;
	long long num,cnt;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d",&n,&m,&q);
		memset(a,0,sizeof(a));
		num=0;
		for(int i=0;i<q;i++)
		{
			scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
			num+=a[i].w;
		}
		num=(num+1)/2;	//所有的人 中位数 
		sort(a,a+q,cmp1);
		cnt=0;
		for(int i=0;i<q;i++)	//中位数所在横坐标 
		{
			cnt+=a[i].w;
			if(cnt>=num)
			{
//				printf("%d %d==\n",cnt,num);
				xx=a[i].x;
				break;
			}
		}
		sort(a,a+q,cmp2);
		cnt=0;
		for(int i=0;i<q;i++)	//中位数所在纵坐标 
		{
			cnt+=a[i].w;
			if(cnt>=num)
			{
				yy=a[i].y;
				break;
			}
		}		
		printf("Case %d: %d %d\n",k++,xx,yy);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值