SRM457 div1 medium
0:何種類の数字を使うか決める
1:二個つかう数字の余りを決める(組み合わせを求める)
2:一個使う数字の余りを決める(同上)
3:一個使う方は大きい方を使うか小さい方を使うかがある
#include <algorithm> #include <cstring> typedef long long LL; using namespace std; class TheHexagonsDivOne { public: int board[7]; LL cache[200][200]; LL C(int n,int r) { if(n<r) return 0; if(cache[n][r]!=-1) return cache[n][r]; if(r==0 || n==r) return cache[n][r]=1; return cache[n][r]=C(n-1,r)+C(n-1,r-1); } LL calc() { LL r=0; int o[7]; for(int i=0;i<7;i++) o[i]=i; do { int bo[7]; for(int i=0;i<7;i++) bo[i]=board[o[i]]; bool b=true; for(int i=1;i<5 && b;i++) b=(b && bo[i-1]!=bo[i]); b=(b && bo[0]!=bo[5] && bo[4]!=bo[5]); for(int i=0;i<6 && b;i++) b=(b && bo[i]!=bo[6]); if(b) r++; }while(next_permutation(o,o+7)); return r; } LL count(int n) { memset(cache,-1,sizeof(cache)); LL ans=0; board[0]=0,board[1]=1,board[2]=2,board[3]=3,board[4]=4,board[5]=5,board[6]=6; printf("same=0 calc()=%lld\n",calc()/6); ans+=C(n,0)*C(n,7)*(LL)(1<<7)*calc()/6; board[0]=0,board[1]=0,board[2]=2,board[3]=3,board[4]=4,board[5]=5,board[6]=6; printf("same=1 calc()=%lld\n",calc()/6); ans+=C(n,1)*C((n-1),5)*(LL)(1<<5)*calc()/6; board[0]=0,board[1]=0,board[2]=2,board[3]=2,board[4]=4,board[5]=5,board[6]=6; printf("same=2 calc()=%lld\n",calc()/6); ans+=C(n,2)*C((n-2),3)*(LL)(1<<3)*calc()/6; board[0]=0,board[1]=0,board[2]=2,board[3]=2,board[4]=4,board[5]=4,board[6]=6; printf("same=3 calc()=%lld\n",calc()/6); ans+=C(n,3)*C((n-3),1)*(LL)(1<<1)*calc()/6; return ans; } };
残り99問