【USACO】两道简单的ACM试题
来源:互联网 发布:java字符串单个字符 编辑:程序博客网 时间:2024/05/16 17:40
SuperPrime Rib
题目(简述):
找出某一长度的超级素数。所谓的超级素数,例如7331:其中7331是素数,733是素数,73是素数,7是素数。即每次从该数中去掉最后一位数后,依然是素数的素数,被称为超级素数(superprime)。
分析:
判断一个数是不是超级素数,我们需要判断n次,n为这个数的位数。为了使程序更快,我们应该首先判断最高位是不是素数,然后判断最高两位是不是素数……直到判断到这个数本身是不是素数。其次,我们并不需要遍历所有的n位数,因为很多数直接就可以排除掉:除了最高位,其他任何位上有偶数的排除,1开头的数排除,至于为什么,原因很简单,大家可以自己思考。这样之后,我们其实可以生成这样的数,而不是遍历。生成这样的数的时候,注意要按照从小到大的顺序。下面是代码实现。
代码:
Executing... Test 1: TEST OK [0.000 secs, 3048 KB] Test 2: TEST OK [0.000 secs, 3048 KB] Test 3: TEST OK [0.000 secs, 3048 KB] Test 4: TEST OK [0.000 secs, 3048 KB] Test 5: TEST OK [0.000 secs, 3048 KB]/*ID:haxc_xc1PROG:sprimeLANG:C++*/#include <stdio.h>#include <stdlib.h>#include <math.h>int n;bool prime(int num){bool ret=true;int i;for(i=2;i<=sqrt(num);i++){if(num%i==0){ret=false;break;}}return ret;}void deal(int num,int k){if(k==n){if(prime(num)) //搜索到k位的时候,如果满足条件,则直接输出{printf("%d\n",num);}}else{if(prime(num*10+1)) //如果这个数满足,则向下搜索{deal(num*10+1,k+1);}if(prime(num*10+3)){deal(num*10+3,k+1);}if(prime(num*10+5)){deal(num*10+5,k+1);}if(prime(num*10+7)){deal(num*10+7,k+1);}if(prime(num*10+9)){deal(num*10+9,k+1);}}}int main(void){freopen("sprime.in","r",stdin);freopen("sprime.out","w",stdout);scanf("%d",&n);deal(2,1);deal(3,1);deal(5,1);deal(7,1);return 0;}
Checker Challenge
题目:
这个问题是8皇后问题的扩展,读入一个数n,代表n*n的格子,求出所有的方案数,并且输出前3种方案的具体内容。
分析:
笔者写的第一个程序,是基于深度优先搜索,没有任何优化,n=13时运算超时。后来看了若干别人的分析之后,了解到matrix67大牛的一个基于位运算的算法,深表佩服:具体链接:http://www.matrix67.com/blog/archives/266。具体内容里面已经讲述地很清楚了,也就不再赘述。代码部分附上本人所写的基于此思想的C语言的实现。另外,这个题还可以采用对称的思想对其进行优化。
代码(只输出了所有方案的数量,没有输出前3个具体的方案):
#include <stdio.h>#include <stdlib.h>int n;unsigned upperlim;int result;void deal(unsigned row,unsigned ld,unsigned rd,int deep)//row代表列有冲突的,ld代表左斜对角线有冲突的,rd代表右斜对角线有冲突的。deep代表层数或者深度,都可以。{if(row!=upperlim)//还没有放完{unsigned pos=upperlim & ~(row|ld|rd),p;while(pos){p=pos&(-pos); //p为右起第一个安全位置pos=pos^p; //设置禁止位deal(row|p,(ld|p)>>1,(rd|p)<<1,deep+1);}}else{result++;}}int main(void){freopen("checker.in","r",stdin);freopen("checker.out","w",stdout);scanf("%d",&n);upperlim=(1<<n)-1; //upperlim的每一位都表示了该位置是否能够放下deal(0,0,0,1);printf("%d\n",result);return 0;}
- 【USACO】两道简单的ACM试题
- USACO试题beads的两种解法
- 两道简单的面试题 java
- 两道简单的面试题
- ACM典型试题--简单的加密算法(一)
- 两道简单面试题的经典解法
- USACO 两道题目
- USACO 两道题目
- USACO 两道题目
- USACO 两道题目
- USACO 两道题目
- USACO 两道题目
- USACO 两道题目
- 面试的两道试题
- USACO 1.2 两道题目
- 两道普通的面试题
- 两道设计模式的面试题
- 两道有意思的面试题
- 【WindowsDDK】内核字符串操作蓝屏的一个解决办法
- 【经典数据结构算法】(4)二叉树求和为定值的所有路径
- 【翻译】深入解析Windows操作系统(第五版)-第一章
- 【Windows内核原理与实现】读书笔记(一)
- 【Windows内核原理与实现】读书笔记(二)
- 【USACO】两道简单的ACM试题
- 【Windows内核原理与实现】读书笔记(三)
- 【Windows内核原理与实现】读书笔记(四)
- 【Windows内核原理与实现】读书笔记(五)
- 【QT学习】(一)配置Qt+VS2008环境
- 【Qt学习】(二)第一个Qt程序
- 【Windows内核原理与实现】读书笔记(六)
- 【每天进步一点】2012.04.12
- 【Linux】GNU C库 accept函数的逐层下调的研究