好文档 - 专业文书写作范文服务资料分享网站

程序设计大赛 暴力求解

天下 分享 时间: 加入收藏 我要投稿 点赞

程序设计大赛 暴力求解法

一、 知识点

二、 题目应用

1.输入正整数n,按从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j恰好为数字0~9的一个排列,2<=n<=79。 样例输入:62

样例输出:79546 / 01283 = 62 94736 / 01528 = 62

【分析】

枚举0~9的所有排列?没这个必要。只需要枚举fghij就可以算出abcde,然后判断是否有所有数字都不相同即可。不仅程序简单,而且枚举量也从10!=3628800降低至不到1万。由此可见,即使采取暴力枚举,也是需要认真分析问题的。 #include #include int test(int i,int j) {

int a[11]; int k=0;

while(i!=0) //此程序最重要的地方也就是比较这十个数字各不相同,要用数组存起来 {

a[k++]=i; i/=10; }

while(j!=0)

{

a[k++]=j; j/=10; }

int flag;

if(k==9) flag=0; //有十个数,所以这里是9 int l;

for(k=0;k<10;k++)

for(l=k+1;l<10;l++)

if(!flag) //如果flag为0说明分母为四位,则第一位为0 if(a[k]==a[l]||a[k]==0) return 0; else if(flag)

if(a[k]==a[l]) return 0; return 1; }

int main(int argc, char *argv[]) {

int i,n,m;

scanf(\

for(i=1234;i<98765;i++) //i<=49876 {

m=i*n;

if(m>100000) break; else if(test(m,i)) {

printf(\ } }

return 0; }

2 最大乘积

输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列。如果这个最大的乘积不是整数,应输出-1(表示无解)。1<=n<=18, -10<=Si<=10。 样例输入: 3

2 4 -3 5

2 5 -1 2 -1 样例输出: 8 20

【分析】

连续子序列有两个要素:起点和终点,因此只需枚举起点和终点即可。由于每个元素的绝对值不超过10,一共又不超过18个元素,最大可能的乘积不会超过10^18,可以用

long long存下。 #include int main()

{ int n, S[18];

while(scanf(\ { for(int i = 0; i < n; i++) scanf(\

int result[172], count = 0;

//result数组用来存各连续子序列的值,子序列的个数为n(n+1)/2

for(i = 0; i < n-1; i++) //求出各连续子序列的值,存在数组result中

{ result[count] = S[i];

for(int j = i+1; j < n; j++) { count++;

result[count] = result[count-1] * S[j]; }

count++; }

int mid = result[0]; //找出result中的最大值,为所求的值 for(i = 1; i < count; i++)

mid = (mid > result[i]) ? mid : result[i]; if(mid > 0)

printf(\ else

printf(\ }

return 0; }

3.分数拆分

输入正整数,找到所有的正整数x>=y,使得1/k=1/x+1/y

4.判断是否为双基回文数 S<106,比s大的最小的 #include #include

int fun(int x,int n) //将十进制的x转化为n进制,判断是否为回文数 {

int a[100],b[100]; int k=0;

for(int i=0;;i++)

{ a[i]=x%n; x=x/n;

if(x==0) break;

} k=i; int j;

for(j=k,i=0;j>=0;i++,j--) b[i]=a[j];

b[k+1]='\\0'; //求出x的n进制数 int flag=1;

for (i=0;;i++) {

if(i>(k/2)) break; if (b[i]!=b[k-i]) {

flag=0;break; } }

if(flag) return 1; //是n进制的回文数 else return 0; //不是 }

int main()

{ int n,k,flag,i;

while (scanf(\ {

for(;;n++) //枚举,找出最小的 { k=0;

flag = 0;

for(i=2;i<=10;i++) {

if(fun(n,i)) k++;

if(k>=2){flag=1; break;} }

if(flag){ printf(\

} }

return 0; }

4.子集二进制算法介绍:

若集合S包含n个元素x1, x2, ···, xn, 则用一种简介的表示S的子集的方法是,把它表示成由0和 1组成的串,其中,若xk 属于S,则串中的第K个元素为1,否则为0. 例如,若n = 3, 则8(= 23)个串及其对应的子集如下所示:

000 空集 100 {x1 }

001 {x3} 101 {x1, x3} 010 {x2} 110 {x1, x2}

011 {x2,x3 } 111 {x1, x2, x3} 通过这个列表,可以看出如何按照上面的次序来生成这些0-1串:先寻找最右边的0,把它变成1,然后把它右边的所有数字都变成0.

3. 问题 假金币

Gold Bar银行收到可靠消息:在M组金币中每组都有一个重量不同的假金币(其他金币的重量相同)。经济危机之后他们只有一台天平可用。用这台天平,可以称量出左边托盘中的物体是轻于、重于或等于右边托盘中的物体。

为了分别出假金币,银行职员将所有的金币编为1-N号。然后用天平称量不同的金币组合,每次仔细记载称量金币的编号和结果。

现在要求编写一个程序,帮助银行职员根据称量记录找出假金币的编号。 输入:

第一行为金币组数M,后面是每组金币情况。

第二行输入两个空格隔开的整数N和K,N是金币的总数(2<=N<=1000),K是称量的次数(1<=K<=100)。随后的2K行记录称量的情况和结果,连续两行记录一次称量:第1行首先是Pi(1<=Pi<=N/2) ,表示两边托盘中放置的金币数目,随后是左边托盘中Pi个金币编号和右边托盘中Pi个金币编号,所有的数之间都由空格隔开;第2行用<,>,=和记录称量结果。

<表示左边托盘中的金币比右边的轻 >表示左边托盘中的金币比右边的重 =表示左右两边托盘中的金币一样重

输出

输出假金币的编号。如果根据称量记录无法确定假金币,输出0。 输入样例 1 5 3

2 1 2 3 4 <

1 1 4 =

1 2 5 = 输出样例 3

short jo(int j,int *s, char c) {

//函数判断假设j号金币是假的与称量结果是否矛盾 //s是称重记录,其第一个元素是砝码个数 //c是称量结果 m=s[0]<<1;

程序设计大赛 暴力求解

程序设计大赛暴力求解法一、知识点二、题目应用1.输入正整数n,按从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j恰好为数字0~9的一个排列,2<=n<=79。样例输入:62样例输出:79546/01283=629473
推荐度:
点击下载文档文档为doc格式
4i1iv08c9p7l7tx2asin
领取福利

微信扫码领取福利

微信扫码分享