指数级枚举:1到n任意选取的所有方案数:
#include<bits/stdc++.h> using namespace std; int n,a[1100],vis[1100],cnt,m; inline void dfs(int x) { if(x==n) { for(int i=1;i<=n;i++) if(vis[i]) cout<<a[i]<<' '; cout<<endl; return; } vis[x+1]=1; dfs(x+1); vis[x+1]=0; dfs(x+1); } int main() { freopen("1.in","r",stdin); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; dfs(0); }
组合型枚举:1到n中选m个的所有方案数:
#include<bits/stdc++.h> using namespace std; int n,a[1100],vis[1100],cnt,m,o; inline void dfs(int x) { if(o>m||(o+n-x)<m) return; if(x==n) { for(int i=1;i<=n;i++) if(vis[i]) cout<<a[i]<<' '; cout<<endl; cnt++; return; } vis[x+1]=1;o++; dfs(x+1); vis[x+1]=0;o--; dfs(x+1); } int main() { //freopen("1.in","r",stdin); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; dfs(0); cout<<cnt<<endl; }
排列性枚举:1到n的全排列:
#include<bits/stdc++.h> using namespace std; int n,a[1100],vis[1100],cnt,m,ans[1100]; inline void dfs(int x) { if(x==n) { for(int i=1;i<=n;i++) cout<<a[ans[i]]<<' '; cout<<endl; return; } for(int i=1;i<=n;i++) { if(!vis[i]) { vis[i]=1; ans[x+1]=i; dfs(x+1); vis[i]=0; ans[x+1]=0; } } } int main() { freopen("1.in","r",stdin); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; dfs(0); }
Fractal Streets:
分形的街道
时间限制:1000ms内存限制:65536K
总提交数:2090接受数:596
描述
随着我们越来越大的城市对现代化的日益渴望,对新的街道设计的需求也随之而来。克里斯是负责这些设计的不幸的城市规划者之一。每年的需求都在增加,今年他甚至被要求设计一个全新的城市。
克里斯现在不需要更多的工作,因为他和其他优秀的官僚一样,非常懒惰。考虑到这是他与大多数计算机科学家共同的性格特点,他最亲密的朋友之一保罗实际上是一名计算机科学家也就不足为奇了。正是保罗提出了一个让克里斯成为同龄人英雄的绝妙想法:分形街道!通过使用希尔伯特曲线,他可以很容易地填充任意大小的矩形图,而只需很少的工作。
1阶希尔伯特曲线由一个“杯”组成。在2阶希尔伯特曲线中,那个杯子被四个更小但相同的杯子和三条相连的路所取代。在希尔伯特曲线的3阶中,这四个杯子依次被四个相同但更小的杯子和三条相连的路所取代。在杯子的每个角落,都有一条车道(带有邮箱),用来给房子编号,编号顺序很简单。左上角的房子是1号,相邻两间房子的距离是10m。
这种情况如图2所示。正如你所看到的,分形街道的概念成功地消除了无聊的街道网格的需要,而仍然需要从我们的官僚非常少的努力。
为了表达他们的感激之情,几位市长向克里斯提供了一所房子,这所房子位于许多用他自己的新方案建造的新社区之一。克里斯现在想知道,这些房子中哪些能让他买到离当地城市规划办公室最近的房子(当然,每个新社区都有一个)。幸运的是,他不用沿着街道开车,因为他的新公司“car”就是那些新型飞行汽车之一。这辆高科技汽车可以让他从车道直行到新办公室的车道。你能编写一个程序来确定每架飞机的飞行距离(不包括起飞和降落时的垂直距离)吗?
输入
在输入的第一行是一个正整数,测试用例的数量。然后对于每个测试用例:
一条包含三个正整数的直线,n < 16和h, o < 231,指定希尔伯特曲线的顺序,以及提供的房屋和当地城市规划办公室的门牌号码。
输出
对于每个测试用例:
其中一条线包含了Chris飞到他的作品的距离,单位是米,四舍五入到最近的整数。
/* 这个题真的很毒瘤... 好吧,起码让我对分治或递归有更深刻的理解了 首先getz求的是对当前城市的坐标 然后得到上一级的坐标后,怎样转换便是要思考的问题,这里迷一下午的点便是左下角的坐标转化,现在才明白他们的进出口方向不同 所以要先逆时针再水平翻转...因为你是按大小得到的坐标转化时应当考虑它再这一级城市中大小又是怎么分布的 还有的毒瘤就是竟然卡精度 好吧,无话可说 起码又让我知道了double的精度比较小吧. 最后,又学会了函数传结构体,意外的惊喜.. */ #include<bits/stdc++.h> #define ll long long using namespace std; pair<ll,ll>a,b; ll T,n,z1,z2; inline pair<ll,ll> getz(ll p1,ll p2)//getz表示在当前等级下的坐标. { if(p1==0) return make_pair(0,0); ll cnt=1ll<<(2*p1-2),len=1ll<<(p1-1); pair<ll,ll> pos=getz(p1-1,p2%cnt); ll x=pos.first,y=pos.second; ll z=p2/cnt; if(z==0) return make_pair(y,x); if(z==1) return make_pair(x,y+len); if(z==2) return make_pair(x+len,y+len); if(z==3) return make_pair(2*len-y-1,len-x-1); } inline double distance() { ll x1=a.first,yy1=a.second; ll x2=b.first,y2=b.second; double ans=sqrt((x1-x2)*(x1-x2)+(yy1-y2)*(yy1-y2))*10; return ans; } int main() { cin>>T; while(T--) { cin>>n>>z1>>z2; a=getz(n,z1-1); b=getz(n,z2-1); printf("%.0lf ",distance()); } return 0; }
典型的递归思想。
先以其中一个街道为基准,每次都向下查找,查找到的值处理就行...