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;
}