题目来源 hdu4484 -- 4492
hdu4484 最水的一道,直接一直找到1为止
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int a[11000];
int main()
{
int N;
int n;
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d%d",&i,&n);
if(n==1)
printf("%d 1\n",i);
else
{
int j=1;
a[0]=n;
while(j>0)
{
if(n%2==0)
n=n/2;
else
n=3*n+1;
a[j]=n;
if(a[j]==1)
break;
j++;
}
sort(a,a+j+1);
printf("%d %d\n",i,a[j]);
}
}
return 0;
}
hdu 4485
找规律,就是给定一个长度在10000以内的数字串,用b进制表示的,让求这个b进制表示的数字串%(b-1)
规律就是数字串各个数字之和%(b-1)。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
char s[10000005];
int main()
{
int T;
scanf("%d",&T);
int b;
for(int i=1;i<=T;i++)
{
scanf("%d%d",&i,&b);
getchar();
gets(s);
int len=strlen(s);
int ans=0;
for(int j=0;j<len;j++)
{
ans+=(s[j]-'0');
//cout<<"hfhhf:"<<ans<<endl;
}
printf("%d %d\n",i,ans%(b-1));
}
return 0;
}
hdu 4486
题意:让求三角形的个数,若三边互不相等,按两个算。
一定要找对方法,不然就会TLE。
我一开始枚举两条边用了两个for循环,果断TLE.
后来想到枚举一条最小边,最大边范围就确定了,但是等边和等腰还是不好去判断。
再后来就是等边和等腰提前判断,然后枚举一条最小边,确定最大边范围,使得a、b、c互不相等就行了。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
int n;
for(int i=1;i<=T;i++)
{
int a,b,c;
scanf("%d%d",&i,&n);
int ans=0;
for(int a=n/4;a<=n/2;a++) //等腰或等边
{
if(2*a>n-2*a&&a+a<n)
ans++;
}
// cout<<"ans:"<<ans<<endl;
for(a=1;a<=n/3;a++)
{
int l=(n-a)/2+1;
int r=n-2*a-1;
if(n%2==0)
r=min(r,n/2-1);
else
r=min(r,n/2);
if(r>=l)
ans+=(r-l+1)*2;
}
}
return 0;
}
hdu 4488
一道模拟题,只要将400*400的矩阵数字模拟出来就行了。
注意一点就是0的处理,为0时,将分子置为0,分母为1,即0/1,这样不影响通分操作,因为0和非0整数的最大公约数为1. 这个建议是大神提供的,自己没想到,经验太少。
交题还犯二了,hdu上只认__int64, bnu上认long long 计算每一行的第一个数时,要边约分边加和。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
__int64 n;
__int64 d;
} s[500][500];
__int64 gcd(__int64 m,__int64 n)
{
if(n==0)
return m;
else
return gcd(n,m%n);
}
void solve()
{
s[0][1].n=1;
s[0][1].d=1;
for(int i=1; i<=400; i++)
{
for(int j=i+1; j>=1; j--)
{
if(j!=1)
{
__int64 dd=gcd(i*abs(s[i-1][j-1].d),j*abs(s[i-1][j-1].n));
s[i][j].d=(s[i-1][j-1].d)*i/dd;
s[i][j].n=(s[i-1][j-1].n)*j/dd;
}
else if(j==1)
{
__int64 a=s[i][i+1].n;
__int64 b=s[i][i+1].d;
__int64 aa=a;
__int64 bb=b;
for(int j1=i; j1>1; j1--)
{
aa=a*s[i][j1].n;
bb=b*s[i][j1].n+a*s[i][j1].d;
__int64 gg=gcd(abs(aa),abs(bb));
a=aa/gg;
b=bb/gg;
}
__int64 rr=gcd(aa,abs(aa-bb));
s[i][1].n=aa/rr;
s[i][1].d=(aa-bb)/rr;
if(s[i][1].d==0)
s[i][1].n=1;
}
}
}
}
int main()
{
solve();
int T;
scanf("%d",&T);
for(int i=1; i<=T; i++)
{
int x,y;
scanf("%d%d%d",&i,&x,&y);
if(s[x][y].d==0)
printf("%d 0\n",i);
else if(s[x][y].n==1)
printf("%d %I64d\n",i,s[x][y].d);
else
printf("%d %I64d/%I64d\n",i,s[x][y].d,s[x][y].n);
}
return 0;
}
hdu 4489
题意:有n个身高互不相等的士兵,排成一排,只能按如下规律排列:一个士兵比他两边的士兵都低,或者都高。
如:有四个士兵,身高1、2、3、4 排列1 3 2 4 符合要求,3比1、2都大, 2比3 ,4 都小。
解题思路:最重要的是要了解一点:n个士兵的排列只能!!是第2个比1,3个都高,然后第3个比2,4个都低,然后第4个比3,5个都高。。。。。。。
!!!!或第2个比1,3个都低,然后第3个比2,4个都高,然后第4个比3,5个都低。。。。。。。
两种排列方式的数目是相等的。
求n,个人的排列可由前面求出的1-n-1个人的排列求出, 按第n个人的位置来求,他左边可能有0,1,。。。n-1个人
左边有0个人,右边n-1个人排列方式只能是!!这种排列,有f[n-1]/2中,依次求
。。。。。。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
long long f[22];
__int64 g[22];
long long ff() //求阶乘
{
f[1]=1;
for(int i=2;i<=20;i++)
f[i]=f[i-1]*i;
}
long long C(int n,int m) //求组合数
{
return f[n]/f[m]/f[n-m];
}
void solve()
{
g[1]=1;
g[2]=2;
for(int i=3;i<=20;i++)
{
g[i]+=g[i-1]; //第i个人左边或右边有0个人
g[i]+=(g[i-2]*(i-1)); //第i个人左边或右边有1个人
for(int j=2;j<=i-3;j++) //第i个人左边有j个人
g[i]+=((g[j]*g[i-j-1]/4)*(C(i-1,j))); //因为j个人的排列有一半符合要求,
//j-i-1个人的排列也只有一半符合要求,所以除4.
}
}
int main()
{
ff();
solve();
int T;
scanf("%d",&T);
int q;
for(int i=1;i<=T;i++)
{
scanf("%d%d",&i,&q);
printf("%d %I64d\n",i,g[q]);
}
return 0;
}
hdu 4492
理解了题意,很简单,只是我读了三遍才懂
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
char s[100];
char ss[600];
int b[600];
int main()
{
int T;
int n;
scanf("%d",&T);
for(int i=1;i<=T;i++)
{
scanf("%d",&i);
getchar();
gets(s);
int len=strlen(s);
scanf("%d",&n);
int d=0;
for(int j=0;j<n;j++)
{
scanf("%d",&b[j]);
}
d=0;
for(int j=0;j<n;j++)
{
d=d+b[j];
if(d>=len)
d=d%len;
if(d<0)
d=len+d;
ss[j]=s[d];
}
ss[n]='\0';
printf("%d ",i);
puts(ss);
}
return 0;
}
hdu 4487
请看DP专题。