此次感受:只做出了b题,a题用排列组合推了好久都没有推出来,d题很靠近答案了,但是没有想到有unsigned long long int 这样大的数。开心的是这次赛后交流很有收获,无论打的怎么样,希望每一步都走的很扎实,对得起我对知识和经历的尊重。
A.hdu6243——排列组合推公式
<一>
有人说他直接手推了前3个,就猜是是不是n-1.
<二>
有人用stl中的next——permutation打表看结果,再看看什么规律
注意,permutation只能全排列出n<=11的。而且到n=11的时候要等一会才会出来。
#include<cstdio>
#include<algorithm>
using namespace std;
int judge(int *arr,int len)
{
int cnt=len;
for(int i=0;i<len;i++)
if(arr[i]==i)cnt--;
return cnt;
}
int main(void)
{
/* int arr[12];
for(int i=2;i<=10;i++)
{
for(int d=0;d<i;d++)arr[d]=d;
int ans=0,cnt=1;
while(next_permutation(arr,arr+i))
{
ans+=judge(arr,i);
cnt++;
}
printf("ans=%d cnt=%d i=%d %llf\n",ans,cnt,i,(double)ans/(double)cnt);
}*/
int cas;
scanf("%d",&cas);
for(int i=1;i<=cas;i++)
{
int n;
scanf("%d",&n);
printf("Case #%d: %d.0000000000\n",i,n-1);
}return 0;
}
<三>网上dl的数学组合思想
一个数在正确的位置的排列方法有(n-1)!个,那么不在的就有n!-(n-1)!,
由于这题是每种排列方法中不在正确位数的期望,因此所有排列方法中元素不在正确位置的个数的和可以拆分单独的一个数不在正确位置的排列方法数的和。也就是n*(n!-(n-1)!)。
由于样本数为n!,上式再除以它,即得到n-1.
B:hdu6247——模拟大水题
D:hdu6253——推导得公式
做题思路:读罢,居然先用手模拟了一遍来了解题意,画的要疯了,于是想为什么不直接用bfs,于是先用bfs打出来,发现符合样例,再打出所有的,发现有一个规律,那就是差值是一个公差为28的等差数列。欣喜若狂,但是测最大数据1e9的时候却出错了,出现混乱数,明明用的是long long int了,怀疑是哪里错了,却找不到原因,后来赛后交流,原来是要用unsigned long long int,而且int 和 unsigned 加减乘除会出错,所以在输入的那个数也要改成unsigned。
以下中注释部分为推导的。
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
/*struct re{int x,y,time;};
int sx[]={0,-2,-1,-2,-1,2,1, 2, 1};
int sy[]={0,-1,-2, 1, 2,1,2,-1,-2};
int ans[1000];
int vi[10000][10000];
*/
/*queue<re>all;
void bfs()
{
re tem;
tem.x=1000;tem.y=1000;tem.time=0;
vi[tem.x][tem.y]=1;ans[0]=1;
all.push(tem);
while(!all.empty())
{
re get=all.front();
all.pop();
//printf("kkk get.time=%d\n",get.time);
for(int i=1;i<=8;i++)
{
re now;
now.x=get.x+sx[i];
now.y=get.y+sy[i];
now.time=get.time+1;
//printf("now.x=%d now.y=%d\n",now.x,now.y);
if(now.x<0||now.y<0)printf("ggg\n");
if(now.time>400)return;
if(vi[now.x][now.y]==0){ans[now.time]++;vi[now.x][now.y]=1;}
else continue;
all.push(now);
}
}
}*/
int main(void)
{
// memset(ans,0,sizeof(ans));
// bfs();
unsigned long long int biao[7]={1,9,41,109,205,325,473};
int cas;
/*for(int i=1;i<=100;i++)
{//ans[i]+=ans[i-1];
bei[i]+=bei[i-1];
printf("i=%d %d %d bei=%d\n",i,ans[i],ans[i]-ans[i-1],bei[i]);
if(i<6)printf("%d\n",bei[i]);
else
{int gus=(ans[6]*2+(i-6)*28)*(i-5)/2+bei[5];
printf("gus=%d \n",gus);
}
}*/
scanf("%d",&cas);
for(int ca=1;ca<=cas;ca++)
{
unsigned long long int n;
scanf("%llu",&n);
unsigned long long int b;
if(n<6)b=biao[n];
else b=(148+(n-6)*14)*(n-5)+biao[5];
printf("Case #%d: %llu\n",ca,b);
}
return 0;
}