exam_11.10
来源:互联网 发布:基因重编程 编辑:程序博客网 时间:2024/06/16 06:41
炮(cannon)
【题⽬描述】 众所周知,双炮叠叠将是中国象棋中很厉害的⼀招必杀技。炮吃⼦时必须 隔⼀个棋⼦跳吃,即俗称“炮打隔⼦”。 炮跟炮显然不能在⼀起打起来,于是rly ⼀天借来了许多许多的炮在棋盘上摆了起来……他想知道,在N×M的矩形⽅格 中摆若⼲炮(可以不摆)使其互不吃到的情况下⽅案数有⼏种。 棋⼦都是相同的。
【输⼊说明】 ⼀⾏,两个正整数N和M。
【输出说明】 ⼀⾏,输出⽅案数mod 999983。
【样例输⼊】 1 3
【样例输出】 7
【数据范围】 对于40%的数据,N<=4,M<=4 对于70%的数据,N<=100,M<=8 对于100%的数据,N<=100,M<=10
题解:
[AHOI2009中国象棋] 原题
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;int n, m;long long f[111][111][111], ans;long long MOD = 999983;int main() { freopen("cannon.in", "r", stdin); freopen("cannon.out", "w", stdout); scanf("%d%d", &n, &m); f[0][0][0] = 1; for(int i = 1; i <= n; i++) { for(int j = 0; j <= m; j++) { for(int k = 0; k <= m - j; k++) { if(k && i == 1) break; long long & now = f[i][j][k]; now += f[i - 1][j][k]; if(j >= 1) now = (now + f[i - 1][j - 1][k] * (m - j + 1 - k)) % MOD; //µÚiÐзÅÒ»¸ö ÇÒ·ÅÔÚÁË֮ǰûÓÐÅÚµÄÒ»ÁС£¡£ if(j + 1 <= m && k >= 1) now = (now + f[i - 1][j + 1][k - 1] * (j + 1)) % MOD; //µÚiÐзÅÒ»¸ö ÇÒ·ÅÔÚÁË֮ǰÓÐÒ»¸öÅÚµÄÒ»ÁÐ if(j >= 2) now = (now + f[i - 1] [j - 2][k] * ((m - j + 2 - k) * (m - j + 2 - k - 1) / 2)) % MOD; //µÚiÐзÅÁ½¸ö ÇÒ¶¼·ÅÔÚÁË Ã»ÓÐÅÚµÄÁÐ if(k >= 1) now = (now + f[i - 1][j][k - 1] * (m - j - k + 1) * (j)) % MOD; //µÚiÐзÅÁ½¸ö Ò»¸ö·ÅÔÚûÓÐÅÚµÄÒ»ÁÐ Ò»¸ö·ÅÔÚÁËÓÐÒ»¸öÅÚµÄÒ»ÁÐ if(j + 2 <= m && k >= 2) now = (now + f[i - 1][j + 2][k - 2] * ((j + 2) * (j + 2 - 1) / 2) ) % MOD; //µÚiÐзÅÁ½¸ö ¶¼·ÅÔÚÁËÓÐÒ»¸öÅÚµÄÒ»ÁÐ now %= MOD; // cout<<"f["<<i<<"]["<<j<<"]["<<k<<"] = "<<now<<endl; } } } for(int i = 0; i <= m; i++) for(int j = 0; j <= m - i; j++) ans = (ans + f[n][i][j]) % MOD; ans %= MOD; printf("%lld\n", ans);}/**/
三维状态的DP⾞(rook)【题⽬描述】 众所周知,⾞是中国象棋中最厉害的⼀⼦之⼀,它能吃到同⼀⾏或同⼀列 中的其他棋⼦。⾞跟⾞显然不能在⼀起打起来,于是rly⼀天又借来了许多许多 的⾞在棋盘上摆了起来……他想知道,在N×M的矩形⽅格中摆最多个数的⾞使 其互不吃到的情况下⽅案数有⼏种。但是,由于上次摆炮摆得实在太累,他为 了偷懒,打算增加⼀个条件:对于任何⼀个⾞A,如果有其他⼀个⾞B在它的上 ⾯(⾞B⾏号⼩于⾞A),那么⾞A必须在⾞B的右边(⾞A列号⼤于⾞B)。 棋⼦都是相同的。 【输⼊说明】 ⼀⾏,两个正整数N和M。 【输出说明】 ⼀⾏,输出⽅案数的末尾50位(不⾜则直接输出)。 【样例输⼊】 2 2【样例输出】 1 【数据范围】 对于20%的数据,N<=10,M<=10。 对于40%的数据,N<=40,M<=40。 对于70%的数据,N<=10000,M<=10000。 对于100%的数据,N<=1000000,M<=1000000。
题解:
排列组合C(n,m) + 质因数分解(快速质因数分解John M. Pollard方法 n ^(1/4)) + 高精乘
如果 n < m, 交换一下.一开始写的递推 O(m * (n - m +1)) 后来发现可以矩阵乘法, 再后来发现可以两个sum转换前缀和。。。。然而不是正解。。。。注意坑点:如果答案超过50位,则前导零不能删,若答案不超过50位,不要前导零。
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;#define debug cout<<"Orzzzzzzzzzzzzzzzzzzzzzzzzzzz"<<endl;long long n, m;long long check[1111111], prime[1111111], js[1111111], ans[111];void work(long long now, int val) { for(int i = 1; i <= prime[0]; i++) { long long tmp = now; while(tmp) { if(val) js[i] += tmp / prime[i]; else js[i] -= tmp / prime[i]; tmp /= prime[i]; } }}int work_2(long long x, int y) { while(y--) { for(int i = 1; i <= ans[0]; i++) ans[i] *= x; for(int i = 1; i <= ans[0] + 8 && i <= 50; i++) if(ans[i] > 9) { ans[i + 1] += ans[i] / 10; ans[i] %= 10; } ans[0] = min(50, (int)ans[0] + 8); while(ans[ans[0]] == 0) ans[0]--;// while(ans[ans[0] + 1]) ans[0]++; //DEBUG!!!!²»ÒªÕâôд£¡£¡£¡£¡ 901111 »áÔÚ0´¦Ìø³ö£¡£¡£¡£¡£¡Ê¹ans¡¾0¡¿ = 4 // cout<<y<<" dfdfdfd "<<endl;// getchar(); }}int main() { freopen("rook.in", "r", stdin); freopen("rook.out", "w", stdout); ans[++ans[0]] = 1; cin>>n>>m; if(n < m) { n += m; m = n - m; n -= m; } for(int i = 2; i <= n; i++) { if(!check[i]) prime[++prime[0]] = i; for(int j = 1; j <= prime[0]; j++) { if(prime[j] * i > n) break; check[prime[j] * i] = 1; if(i % prime[j] == 0) break; } } work(n, 1); work(m, 0); work(n - m, 0); for(int i = 1; i <= prime[0]; i++) { if(js[i] >= 1) work_2(prime[i], js[i]);// cout<<js[i]<<' '<<i<<' '<<prime[i]<<endl; } int xx = 50; while(ans[xx] == 0 && xx > 1) xx--; if(ans[51]) xx = 50; for(int i = xx; i >= 1; i--) cout<<ans[i]; return 0;}
皇后(queen)【题⽬描述】 众所不知,rly现在不会玩国际象棋。但是,作为⼀个OIer,rly当然做过⼋ 皇后问题。这⾥再啰嗦⼏句,皇后可以攻击到同⾏同列同对⾓线,在n*n的⽅格 中摆n个皇后使其互不攻击到,求不同的解的数量,这就是经典的n皇后问题。 现在问题推⼴到n皇后问题,这个问题对于你⽽⾔实在是⼩菜⼀叠。但因为上⼀ 次rly把棋盘弄破了,又拿不出新的,所以rly打算难⼀点点,问题就是破棋盘上 的n皇后问题。他想知道……(你们懂的)。 棋⼦都是相同的。 【输⼊说明】 ⼀⾏,⼀个正整数N。 接下来N⾏,每⾏N个数,要么为0,表⽰没坏,要么1,表⽰坏了。 【输出说明】 ⼀⾏,输出不同的解的数量。 【样例输⼊】 4 1 0 1 1 1 1 1 0 0 1 1 1 1 1 0 1 【样例输出】 1 【数据范围】 对于40%的数据,N<=13。 对于100%的数据,N<=16。 其中有30%的数据,棋盘没有破(你可以认为rly又去买了⼀个新的)。
题解:
位运算的n皇后 比数组记录可选位置要快很多
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;int xie_sum[50], xie_unsum[50], hang[50], lie[50];long long ans;int cs[50];int n, cnt;long long db[32] = {0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712};struct node { int x, y; bool operator < (const node & xx) const { return x < xx.x; }}ha[356];int lb(int now) { return now & (-now);}int dfs(int now, int lie, int xie_l, int xie_r) { int nn = cs[now] & lie & xie_l & xie_r; if(now > n) { ans++; return 0; } while(nn) { int tmp = lb(nn); int x1 = lie, x2 = xie_l, x3 = xie_r; x1 ^= tmp; x2 ^= tmp; x3 ^= tmp; x2 <<= 1; x2 |= 1; x3 >>= 1; x3 |= 1 << (n - 1); if(x2 >> n) x2 -= 1 << n;// cout<<now<<' '<<nn<<' '<<tmp<<' '<<x1<<' '<<x2<<' '<<x3<<" dfdfdfdf "<<endl; nn -= tmp; dfs(now + 1, x1, x2, x3); }}int main() { freopen("queen.in", "r", stdin); freopen("queen.out", "w", stdout); scanf("%d", &n); for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { int xx; scanf("%d", &xx); if(!xx) cs[i] |= (1 << (n - j)); }// cout<<"cs["<<i<<"] = "<<cs[i]<<endl; }// sort(ha + 1, ha + 1 + cnt);// if(cnt == n * n) {// cout<<db[n]<<endl;// return 0;// } dfs(1, (1 << n) - 1, (1 << n) - 1, (1 << n) - 1); cout<<ans<<endl; return 0;}/*41 0 1 11 1 1 00 1 1 11 1 0 1long long db[32] = {0, 1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712}40 0 0 00 0 0 00 0 0 00 0 0 0140 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0*/
0 0
- exam_11.10
- 10
- 10
- 10
- 10
- 10
- 10
- 10
- 10
- 10%
- 10
- 10
- 10
- 10
- 10
- 10
- 10
- #10
- Python程序:批理转化Excel成CSV文件
- 实现队列
- SpringMVC源码剖析(二)- DispatcherServlet的前世今生
- hdu1072(dfs)
- 基于STM32F4的提升小波(二代小波)分解程序说明
- exam_11.10
- 逻辑回归及相关问题的总结
- usaco ★Subset Sums 集合
- Basic Calculator
- Python--通过XPath实现网络爬虫
- 蓝牙的基本使用二
- Unity3D开发小贴士(六)Lua里调用C#扩展
- Node.js基础(一)
- 11.8时空传送