c++20701除法(刘汝佳1、2册第七章,暴搜解决)

20701除法
难度级别: B; 编程语言:不限;运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B

试题描述

    输入正整数n,按从小到大的顺序输出所有满足表达式abcde/fghij=n的abcde和fghij,其中a~j恰好为数字0~9的一个排列。 如果没有符合题意的数,输出0。本题所说的五位数可以包括前导0的,如01234在这里也称为五位数。

输入

一个正整数n 

输出

若干行,每行包括两个符合要求的五位正整数(每行的两个数先大后小),两数之间用一个空格隔开。 

输入示例

62

输出示例

79546 01283
94736 01528

其他说明

数据范围 2≤n≤79;题目中的从小到大指的是输出数据每行的第一个数是从小到大的顺序。 

据题意可知,这道题可以用暴搜解决,不过一般的暴搜在这题上要每一位都用一个循环,这道题2个数,每个数5位(万位可以为0),按理说10位数,10个循环,对不?但这里只要枚举一个数,另一个数可以求出来的。我们当然选择枚举小的那个数(其实哪个都一样),也就是除数,那么被除数应该用这个枚举出来的数×n;如果枚举大的那个数,也就是被除数,那么除数应该用这个枚举出来的数÷n。我们用p[10]数组存储这两个数,同时方便全查找是否有重复。这是最基础的办法,也是最好理解的办法。

这题是刘汝佳一册P114或刘汝佳二册P182的题,第七讲“暴力求解法”的第一题,只是讲了一下思路,没给代码。在这之前说一下,这道题为什么一定要只要枚举一个数。我们可以知道,如果枚举0-9的所有排列,会有10!=3628800轮循环,听起来枚举量还不大,是吧?如果只枚举一个,循环量会掉到5!=120轮,比比程序运算量吧!

下面是代码,用的最笨的暴搜,这题n最大79,而且每种数据可能性不多,所以暴搜可以做。

本程序枚举的是除数,然后乘出被除数。

#include<iostream>
using namespace std;
int n,a,b,p[10],h,i;
bool isit,ih;//isit检查每组被除数和除数是否合法,ih检查最后是否有结果
int main()
{
    cin>>n;
    for(p[0]=0;p[0]<=9;p[0]++)//除数万位
        for(p[1]=0;p[1]<=9;p[1]++)//除数千位
            for(p[2]=0;p[2]<=9;p[2]++)//除数百位
                for(p[3]=0;p[3]<=9;p[3]++)//除数十位
                    for(p[4]=0;p[4]<=9;p[4]++)//除数个位
                    {
                        if(p[0]!=p[1] && p[0]!=p[2] && p[0]!=p[3] && p[0]!=p[4] && p[1]!=p[2] && p[1]!=p[3] && p[1]!=p[4] && p[2]!=p[3] && p[2]!=p[4] && p[3]!=p[4])//查找除数是否有重复数字。其实这样可以省去很多后面的被除数运算量!如果算完除数有重复还算被除数,一看很多重复,会做很多无用功。
                        {
                                a=p[0]*10000+p[1]*1000+p[2]*100+p[3]*10+p[4];//计算除数
                                b=a*n;//算出被除数
                                if(9999<b && b<100000) 确保10000<=被除数<=99999,想一想,被除数为什么不能低于1w?

p[5]=b/10000;//以下是分离被除数
                                    p[6]=(b%10000)/1000;
                                    p[7]=(b%1000)/100;
                                    p[8]=(b%100)/10;
                                    p[9]=b%10;
                                    isit=1;//看看这组数是不是无重复数字
                                    for(h=0;h<=9;h++)
                                        for(i=h+1;i<=9;i++)
                                            if(p[h]==p[i]) isit=0;//被除数和除数全排查找有没有重复
                                        if(isit)//如果是1就无重复
                                        {
                                            ih=1;//确保有结果
                                            for(i=5;i<=9;i++) cout<<p[i];//切记先打被除数!忽略了一个事,这里可以直接输出b
                                            cout<<‘ ‘;
                                            for(i=0;i<=4;i++) cout<<p[i];//后打除数!
                                            cout<<endl;
                                        }
                                }
                        }
                    }
    if(!ih) cout<<‘0‘;//没结果出0
    return 0;
}

SCX于2015.7.9发布

本人计算机渣渣,自行写论- -

时间: 2024-10-02 00:58:56

c++20701除法(刘汝佳1、2册第七章,暴搜解决)的相关文章

算法竞赛入门经典(刘汝佳)课后习题前三章答案

本文转载: 第一章习题1-1#include <stdio.h>int main(){int a,b,c;double d;scanf("%d%d%d",&a,&b,&c);d=(double)(a+b+c);printf("%.3lf\n",d/3.0);return 0;} 习题1-2#include <stdio.h>int main(){int f;double c;scanf("%d",&

算法竞赛_入门经典_刘汝佳__(2)

1,有几位数字 #include<stdio.h> int main_2_1_digit(){ int n; while(scanf("%d",&n)){ int count = 0; if(n==0) count = 1; while(n){ count++; n/=10; } printf("%d\n",count); } return 0; } 2,三位数的三个数字 #include<stdio.h> int main_2_2_

UVA1625 Color Length(附 刘汝佳代码)

这是刘汝佳<算法竞赛入门经典第二版>的一道例题,只看书上的解释并没有理解,随后结合着代码才理解了. 解题思路:用d[i][j]表示序列1移走i个元素和序列2移走j个元素的最小"代价", 这个代价指的是由那些已经移出的字母合并而来的序列中已经出现但尚未结束的字母对总距离和的贡献.比如说一个合并而来的序列中有两个那样的字母,第一个在这个序列中后面有3个字母,另一个字母后面有2个字母,那么此时的代价就是2+3,表示这两个字母在这种合并情况下至少能为总距离和贡献5,因为随着向该序列

(凸包模板)(刘汝佳)

struct point{ int x,y;} p[N],stack[N]; bool cmp(point A,point B){ if(A.y==B.y)return A.x<B.x; return A.y<B.y;}int cross(point A,point B,point C){ return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);}void graham(){ sort(p,p+n,cmp); int i; top=0; for(i=0;

bzoj 2732 [HNOI2012]射箭 半平面交(刘汝佳版不超时) + 整型二分处理

题目来源: http://61.187.179.132/JudgeOnline/problem.php?id=2732 题意:   对于一个靶子, 得到两个不等式. 裸地半平面交 . 分析: 用的 一般的 模板,总是TLE . 改成了 刘汝佳 版本 ,依然超时, 所谓的常数太大???? 后来注意到 : 当    判断两个向量平行且 同向 ,取左边的一个,不要用 叉积,用极角判断, 可行. 精度 开 1e -16 , 卡精度严重. 注意:这里 也不需要用 friend 写, 也可以ac. 整型二分

计算几何模板(刘汝佳本)(转载)

转载自: 计算几何模板(仿照刘汝佳大白书风格) 想想自己一个学期连紫皮都没看完就想自杀 // Geometry.cpp #include <bits/stdc++.h> #define LL long long #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 #define PI 3.1415926535897932384626 #define EXIT exit(0); #define DEBUG puts(

刘汝佳 例题10-3 选择与除法

1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<vector> 5 #include<iostream> 6 using namespace std; 7 8 const int maxn = 10000; 9 vector<int> primes; 10 int e[maxn]; 11 12 /** 13 add_factorial(int n,

线段树模板(刘汝佳)

在网上找了好久的模板,感觉刘大神的模板比较好用   http://blog.csdn.net/zhulei19931019/article/details/38706259 点修改 Update(x,v):  把Ax修改为v Query(L,R): 计算区间[qL,qR] 最小值.(也可以求最大值) 1 // Dynamic RMQ 2 // Rujia Liu 3 // 输入格式: 4 // n m 数组范围是a[1]~a[n],初始化为0.操作有m个 5 // 1 p v 表示设a[p]=v

《刘汝佳算法竞赛入门经典》第五章 数论

Skew Binary 斜二进制 斜二进制的每位为0, 或 1, 最低位可以为2. 第k位的...代表 2k+1 -1,给出一个斜二进制数,把他转换成十进制数.正常模拟就好 1 #include <cstdio> 2 #include <cstring> 3 char A[1000]; 4 5 int main() { 6 while (scanf("%s", A) != EOF) { 7 if (A[0] == '0') break; 8 int len =