暴力求解法 之 简单枚举
来源:互联网 发布:js format用法 编辑:程序博客网 时间:2024/04/28 04:27
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<stdio.h>
- #include<string.h>
- int main()
- {
- int i,j,n,s1,s2,flag[10];
- while(~scanf("%d",&n))
- {
- for(i=1234;i<5000;i++)
- {
- memset(flag,0,sizeof(flag));
- /*flag保存每一位数字*/
- s1=i;
- s2=i*n;
- while(s1||s2)
- {
- if(!flag[s1%10])
- {
- flag[s1%10]=1;
- s1/=10;
- }
- else
- break;
- if(!flag[s2%10])
- {
- flag[s2%10]=1;
- s2/=10;
- }
- else
- break;
- }
- for(j=0;j<10;j++)
- if(!flag[j])
- break; /*判断是否是10个各不相同的数字*/
- if(j==10&&i*n<=98765) /*如果数字各不相同*/
- {
- if(i<10000) /*除数是一个四位数,有前导0*/
- printf("%d / 0%d = %d\n",i*n,i,n);
- else
- printf("%d / %d = %d\n",i*n,i,n);
- }
- }
- }
- <span style="font-family: Arial, Helvetica, sans-serif;"> </span>
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<stdio.h>
- #include<string.h>
- const int inf=999999;
- int main()
- {
- long long a[20],s[20];
- long long i,j,n,max;
- while(~scanf("%lld",&n))
- {
- memset(s,0,sizeof(s));
- s[0]=1;
- max=-inf;
- for(i=1;i<=n;i++)
- {
- scanf("%lld",&a[i]);
- s[i]=s[i-1]*a[i];
- /*s[i]表示从第一个数到第i个数的乘积*/
- }
- for(i=1;i<=n;i++) /*子序列长度*/
- {
- for(j=i;j<=n;j++)
- {
- if(s[j]/s[j-i]>max)
- max=s[j]/s[j-i];
- }
- }
- if(max<0)
- max=-1;
- printf("%lld\n",max);
- }
- return 0;
- }
3、分数拆分
输入正整数k,找到所有的正整数x>=y,使得1/k=1/x + 1/y;
样例输入:
2
12
样例输出:
2
1/2 = 1/6 + 1/3
1/2 = 1/4 + 1/4
8
1/12 = 1/156 + 1/13
1/12 = 1/84 + 1/14
1/12 = 1/60 + 1/15
1/12 = 1/48 + 1/16
1/12 = 1/36 + 1/18
1/12 = 1/30 + 1/20
1/12 = 1/28 + 1/21
1/12 = 1/24 + 1/24
从1/12=1/156+1/13可以看出,x可以比y大很多。由于x>=y,有1/x<=1/y,因此1/k-1/y<=1/y,即y<=2*k.这样,只需要在2*k范围之内枚举y,然后根据y尝试计算出x即可。
- #include<stdio.h>
- #include<string.h>
- struct integer
- {
- int X,Y;
- }a[10000];
- int main()
- {
- int i,j,y,k,count;
- while(~scanf("%d",&k))
- {
- memset(a,0,sizeof(a));
- i=count=0;
- for(y=k+1;y<=k*2;y++)
- {
- if(y*k%(y-k)==0)
- {
- count++;
- a[i].X=y*k/(y-k);
- a[i++].Y=y;
- }
- }
- printf("%d\n",count);
- for(j=0;j<i;j++)
- printf("1/%d = 1/%d + 1/%d\n",k,a[j].X,a[j].Y);
- }
- return 0;
- }
4、双基回文数
如果一个正整数n至少在两种不同的禁止下b1和b2下都是回文数(2<=b1,b2<=10),则称n是双基回文数(注意,回文数不能包含前导零)。输入正整数S<10^6,输出比S大的最小的双基回文数。
样例输入: 1600000
样例输出: 1632995
分析:最自然的想法就是:从n+1开始依次判断每个数是否为双基回文数,而在判断时枚举所有可能的基数(2~10),一切都是那么的“暴力”。令人有些意外的是:这样做对于S<10^6这样的“小规模数据”来说是足够快的——双基回文数太多太密了。
- #include<stdio.h>
- int a[30];
- int huiwen(int s[],int n) /*判断是否回文*/
- {
- int i;
- for(i=0;i<=n/2;i++)
- {
- if(a[i]!=a[n-i])
- {
- return 0;
- break;
- }
- }
- return 1;
- }
- int converse(int n,int k) /*把十进制的n转化为k进制*/
- {
- int flag=0,i,j=0;
- while(n)
- {
- a[j++]=n%k;
- n/=k;
- }
- if(huiwen(a,j-1))
- flag=1;
- if(flag) /*n在k进制下是回文数*/
- return 1;
- else
- return 0;
- }
- int main()
- {
- int i,j,k,n,cnt;
- while(~scanf("%d",&n))
- {
- for(j=n+1;;j++)
- {
- int p=0;
- for(i=2,cnt=0;i<=10;i++)
- {
- if(converse(j,i))
- cnt++; /*记录回文次数*/
- if(cnt>=2) /*是双基回文数*/
- {
- p=1;
- break;
- }
- }
- if(p)
- {
- printf("%d\n",j);
- break;
- }
- }
- }
- return 0;
- }
0 0
- 暴力求解法 之 简单枚举
- 暴力求解法 之 简单枚举
- 暴力求解法之简单枚举--除法
- 暴力求解法之简单枚举
- 暴力求解法--简单枚举
- 暴力求解法-简单枚举
- 暴力求解法 7.1简单枚举
- 暴力求解法 之 枚举排列
- 暴力求解法之枚举排列
- 暴力求解法之枚举子集
- 算法竞赛入门经典 暴力求解法 7.1简单枚举 除法
- 算法竞赛入门经典 暴力求解法 7.1简单枚举 最大乘积
- 算法竞赛入门经典 暴力求解法 7.1简单枚举 分数拆分
- 算法竞赛入门经典 暴力求解法 简单枚举 7.1.4 双基回文数
- 算法竞赛入门经典第七章暴力求解法——简单枚举(记录向)
- 【算法学习笔记】13.暴力求解法01 枚举排列
- 暴力求解法中的枚举排列,生成全排列
- [专题]暴力之简单枚举
- 却换不回熟悉的那张脸
- HDU 1753 大明A+B
- Pono更像是一款明星周边
- ubuntu apt-get 卸载学问
- [2012山东ACM省赛] Fruit Ninja II (三重积分,椭球体积)
- 暴力求解法 之 简单枚举
- Linux GCC常用命令
- 基于用例点来度量软件规模并管理进度 之结束语
- VC连接SQLite3的方法(MFC封装类)
- “不包含定义,并且找不到可接受类型的第一个扩展方法”
- 关于一道阿里巴巴笔试题的思考
- topo
- 【教程】HTML5+JavaScript编写flappy bird
- 发力4G和终端,中兴离“中兴”还有多远