简单枚举
讲一下自己的理解,所谓的枚举,一般不能纯暴力枚举的,应该先经过算法的优化,可以利用公式、题目的套路、已知算法进行优化,从而解决问题,目的是在规定的时间内完成。好像算法本来就是对各种暴力的优化,学习算法就是不断的优化优化。想起来C语言老师说过的,“不断地回过头来看自己的代码,用现有知识进行改进,你会发现,收获的远比想象得多”,赞。
725 - Division
仅仅枚举01234到98765,然后用数组代表0~9每一位是否存在。
代码见:725
11059 - Maximum Product
我们只需要两个循环,每次累乘,然后判断一下,用一个变量存储最大值,就能求出最大值。
for(int i = 0; i < n; i++) { long long p = 1; for(int j = i; j < n; j++) { p *= a[j]; if(p > ans) ans = p; } }
10976 - Fractions Again?!
1/k = 1/x + 1/y =》 x = ky/(y-k)(先将x用y和k表示,简化计算)
x>=y>k
=》1/x<=1/y
=》1/x = 1/k -1/y <=1/y
=》1/k<=2/y =》 y<=k*2
然后我们只需要枚举y (k,k*2】即可
for(int y = k+1; y <= k*2; y++) if(k*y%(y-k) == 0)
POJ 1321
看的别人的思路,其实这个还是比较好的,和刘汝佳书上思路差不多(可能所以回溯的都差不多吧),过段时间自己尝试看看能不能写出来更精简易懂的。
代码:
#include<iostream>//POJ 1321 八皇后问题 #include<cstdio> #include<cstring> using namespace std; int s[10][10],vis[10];//棋盘,标记行数 int sum,n,k; void dfs(int row,int cur)//按行搜索 { if(cur==k)//摆放的棋子数 { sum++; return; } if(row>=n)//越过棋盘范围,就out return; for(int j=0;j<n;j++)//搜索这一行的每一列的那个数 { if(s[row][j]&&!vis[j])//如果是可以放棋子的位置,并且还是空的 { vis[j]=1;//既然尝试放了,先标明非空了 dfs(row+1,cur+1);//继续下一行的搜索 vis[j]=0;//如果这一行不满足,即没有放棋子,在标空 } } dfs(row+1,cur);//可能现在已经将k个棋子放完,但我们还要继续搜索是否还有别的摆法 } int main() { char str; while(~scanf("%d%d",&n,&k)) { if(n==-1&&k==-1) break; memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { cin>>str; if(str=='#') s[i][j]=1; else s[i][j]=0; } sum=0; dfs(0,0);//从第一行,从零开始计数 printf("%d\n",sum); } }