贪心专题之 HDU 1050

1、如果没有交叉,总时间应该是多少?
2、影响搬运时间的因素是什么?
3、如果每趟处理都包含最大重叠,处理后的效果是什么?
4、得出什么结论?

 

#include<stdio.h>
#include<algorithm>

int main()
{
     int t, n, i, a, b, min, c[201];
     scanf("%d", &t);
     while( t-- ){
         memset( c, 0, sizeof(c));
         scanf("%d", &n);
         while( n-- ){
             scanf("%d %d", &a, &b);
             if( a > b ){
                 i = a;
                 a = b;
                 b = i;
             }
             for( i = (a+1)/2; i <= (b+1)/2; i++ )  c[i]++;
         }
         min = c[1];
         for( i = 2; i <= 200; i++)
             if( min < c[i] )
                 min = c[i];
         printf("%d\n", min*10);
     }

     return 0;
}

贪心专题之 HDU 2037

#include<iostream>
#include<algorithm>
using namespace std;

struct node{
    int s, e;
};

bool cmp( node a, node b){
    return a.e < b.e;
}

node p[105];

int main()
{
    int n;
    int i, j, k, num;

    while( scanf("%d", &n) != EOF && n != 0 ){
        for( i = 0; i < n; i++ )
            scanf("%d %d", &p[i].s, &p[i].e);
        sort(p, p+n, cmp);
        num = 1;
        j = 0;
        for( i = 1; i < n; i++ ){
            if( p[i].s >= p[j].e ){
                j = i;
                num++;
            }
        }
        printf("%d\n", num);
    }

    return 0;
}

HDU 1114 完全背包问题

 

状态转移方程:

if( dp[j-coin[i].w] != MAX && dp[j] > dp[j-coin[i].w] + coin[i].c )
                    dp[j] = dp[j-coin[i].w] + coin[i].c;

 

#include<iostream>
using namespace std;

#define MAX 0X7ffffff
struct node{
    int w;
    int c;
};
node coin[505];
int dp[10005];

int main()
{
    int t, e, f, n;
    int i, j;
    scanf( "%d", &t );
    while( t-- ){
        scanf( "%d %d", &e, &f );
        f -= e;
        scanf( "%d", &n );
        for( i = 0; i < n; i++ )
            scanf( "%d %d", &coin[i].c, &coin[i].w );
        for( dp[0] = 0, i = 1; i <= f; i++ )
            dp[i] = MAX;
        for( i = 0; i < n; i++ )
            for( j = coin[i].w; j <= f; j++ )
                if( dp[j-coin[i].w] != MAX && dp[j] > dp[j-coin[i].w] + coin[i].c )
                    dp[j] = dp[j-coin[i].w] + coin[i].c;
        if( dp[f] == MAX )
            printf("This is impossible.\n");
        else
            printf("The minimum amount of money in the piggy-bank is %d.\n", dp[f]);
    }

    return 0;
}

 

优先队列用法

在优先队列中,优先级高的元素先出队列。
标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
优先队列的第一种 用法,也是最常用的用法:

priority_queue<int> qi;

通过<操作符可知在整数中元素大的优先级高。
故示例1中输出结果为:9 6 5 3 2

第二种方法:
在示例 1中,如果我们要把元素从小到大输出怎么办呢?
这时我们可以传入一个比较函数,使用functional.h函数对象作为比较函数。

priority_queue<int, vector<int>, greater<int> >qi2;

其中
第二个参数为容器类型。
第二个参数为比较函数。
故示例2中输出结果为:2 3 5 6 9

第三种方 法:
自定义优先级。

struct node
{
    
friend bool operator< (node n1, node n2)
    {
        
return n1.priority < n2.priority;
    }
    
int priority;
    
int value;
};

在该结构中,value为值,priority为优先级。
通过自定义operator<操作符来比较元素中的优先级。
在示例 3中输出结果为:
优先级  值
9          5
8          2
6          1
2          3
1          4
但 如果结构定义如下:

struct node
{
    
friend bool operator> (node n1, node n2)
    {
        
return n1.priority > n2.priority;
    }
    
int priority;
    
int value;
};

则会编译不过(G++编译器)
因为标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。
而且自定义类型的< 操作符与>操作符并无直接联系,故会编译不过。

//代码清单

 

#include<iostream>
#include
<functional>
#include
<queue>
using 
namespace std;
struct node
{
    
friend bool operator< (node n1, node n2)
    {
        
return n1.priority < n2.priority;
    }
    
int priority;
    
int value;
};
int main()
{
    
const int len = 5;
    
int i;
    
int a[len= {3,5,9,6,2};
    
//示 例1
    priority_queue
<int> qi;
    
for(i = 0; i < len; i++)
        qi.push(a[i]);
    
for(i = 0; i < len; i++)
    {
        cout
<<qi.top()<<" ";
        qi.pop();
    }
    cout
<<endl;
    
//示 例2
    priority_queue
<int, vector<int>, greater<int> >qi2;
    
for(i = 0; i < len; i++)
        qi2.push(a[i]);
    
for(i = 0; i < len; i++)
    {
        cout
<<qi2.top()<<" ";
        qi2.pop();
    }
    cout
<<endl;
    
//示 例3
    priority_queue
<node> qn;
    node b[
len];
    b[
0].priority = 6; b[0].value = 1
    b[
1].priority = 9; b[1].value = 5
    b[
2].priority = 2; b[2].value = 3
    b[
3].priority = 8; b[3].value = 2
    b[
4].priority = 1; b[4].value = 4

    
for(i = 0; i < len; i++)
        qn.push(b[i]);
    cout
<<"优 先级"<<'\t'<<"值"<<endl;
    for(i = 0; i < len; i++)
    {
        cout
<<qn.top().priority<<'\t'<<qn.top().value<<endl;
        qn.pop();
    }
    
return 0;
}

暂时记录下……


HDU 题目分类

1001       这个就不用说了吧 
1002       简单的大数 
1003       DP经典问题,最大连续子段和 
1004       简单题 
1005       找规律(循环点) 
1006       感觉有点BT的题,我到现在还没过 
1007       经典问题,最近点对问题,用分治 
1008       简单题 
1009       贪心 
1010       搜索题,剪枝很关键 
1011        
1012       简单题 
1013       简单题(有个小陷阱) 
1014       简单题 
1015       可以看作搜索题吧 
1016       经典的搜索 
1017       简单数学题 
1018       简单数学题 
1019       简单数学题 
1020       简单的字符串处理 
1021       找规律的数学题 
1022       数据结构的题(栈的应用) 
1023       特殊的数(Catalan Number) 
1024       经典DP,最大M子段和 
1025       经典DP,最长递增子序列(要用NLogN的方法过) 
1026       搜索 
1027       数学题(或用STL) 
1028       经典问题,整数拆分,用母函数做 
1029       简单题(一般方法容易超时) 
1030       简单题,可用模拟过 
1031       简单题 
1032       简单题 
1033       模拟题 
1034       Candy Sharing Game
1035       模拟题 
1036       简单题 
1037       简单题,不是一般的简单 
1038       简单题 
1039       字符串处理 
1040       简单题,排序 
1041       简单题,用大数 
1042       大数 
1043       经典搜索题,八数码问题  
1044       稍微有点麻烦的搜索题 
1045       搜索题,可用匹配做 
1046       简单题 
1047       简单的大数  
1048       简单字符串处理 
1049       简单题 
1050       贪心 
1051       经典贪心,也可以用DP 
1052       贪心 
1053       贪心,关于Huffman编码 
1054       二分匹配 
1055       二分匹配 
1056       简单题 
1057       模拟题 
1058       经典问题,丑数,DP 
1059       经典问题,可以用母函数或DP(不针对题目优化都会超时) 
1060       数学题 
1061       数学题 
1062       简单字符串处理 
1063       模拟大数 
1064       简单题 
1065       简单题 
1066       数学题,找规律 
1067        
1068       经典二分匹配 
1069       经典DP 
1070       简单题 
1071       简单数学题 
1072       搜索 
1073       字符串处理 
1074       DP 
1075       字典树 
1076       简单题 
1077        
1078       DP 
1079       博弈(DP) 
1080       DP 
1081       经典DP 
1082       简单题 
1083       二分匹配 
1084       简单题 
1085       母函数 
1086       简单几何题 
1087       简单DP 
1088       字符串处理 
1089~1096 (练习输入输出的8个题目) 
1097       简单数学题 
1098       数学题,注意找规律 
1099       数学题 
 
 模拟题, 枚举
1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 1049 1050 1057 1062 1063 1064 1070 1073 1075 1082 1083 1084 1088 1106 1107 1113 1117 1119 1128 1129 1144 1148 1157 1161 1170 1172 1177 1197 1200 1201 1202 1205 1209 1212(大数取模) 1216(链表)1218 1219 1225 1228 1229 1230 1234 1235 1236 1237 1239 1250
1256 1259 1262 1263 1265 1266 1276 1279 1282 1283 1287 1296 1302 1303 1304 1305 1306 1309 1311 1314
复杂模 拟

搜索,递归求解
1010 1016 1026 1043(双广) 1044 (BFS+DFS) 1045 1067 1072 1104 1175 1180 1195 1208 1226 1238 1240 1241 1242 1258 1271 1312 1317
博奕
1079

动态规划
1003 1024 1025 1028 1051 1058 1059 1069 1074 1078 1080 1081 1085 1087 1114 1158 1159 1160 1171 1176 1181 1203 1224 1227 1231 1244 1248 1253 1254 1283 1300

数学,递推,规律
1005 1006 1012 1014 1018 1019 1021 1023 1027 1030 1032 1038 1041 1046 1059 1060 1061 1065 1066 1071(微积分) 1097 1098 1099 1100 1108 1110 1112 1124 1130 1131 1132 1134 1141 1143 1152 1155(物理题) 1163 1165 1178 1194 1196(lowbit) 1210 1214 1200 1221 1223 1249 1261 1267 1273 1290 1291 1292 1294 1297 1313 1316
数论
1164 1211 1215 1222 1286 1299

计算几何
1086 1115 1147
贪心
1009 1052 1055 1257

并查集
1198 1213 1232 1272
线段树,离散化
1199 1255
图论
最短路相关的问 题 1142 1162 1217 1301
二分图问题 1054 1068 1150 1151 1281
其他
1053 (huffman)  1102(MST)  1116(欧拉回路) 1233(MST) 1269(强连通)
数据结构
1103(堆+模 拟)1166(数状树组)1247 1251 1285(Topol) 1298
汉诺塔系列
1207
最近顶点对 1007

 

1500  DP
1501  DP
1502  DP or 记忆化
1503  DP
1504  模拟
1505  DP
1506  DP
1507  2分匹配
1508  记忆化容易点
1509  模拟
1510  DP
1511  搜索可以过
1512  左偏树
1513  DP
1514  DP
1515  DFS
1516  DP
1517  博奕
1518  搜索
1519  DP(不确定)
1520  树状DP
1521  数学题,母函数什么的。其实都可以过
1522  稳定婚姻
1523  DP
1524  博弈
1525  博弈
1526  Maxflow
1527  博弈
1528  2分匹配
1529  简单题
1530  最大团
1531  差分约束
1532  Maxflow 入门题
1533  KM Or 最小费用流
1534  差分约束
1535  差分约束
1536  博弈
1537  模拟 加置换群的理论 CODE可以短些,其实没必要。。。
1538  很有意思的题目。据说是Microsoft亚洲总裁面试的题目
1539  搜索
1540  线段树
1541  树状数组
1542  离散,线段树
1543  线段树
1544  简单的
1545  DP 
http://acm.hdu.edu.cn/forum/htm_data/18/0608/2050.html
1546  搜索
1547  模拟
1548  模拟
1551  2分答案
1553 
1554
1555  简单
1556  技巧。数学
1557  搜索
1558  并查 + 线段判交
1559  DP
1560  减支 + 搜索
1561  树状DP
1562  暴力 between 1000 and 9999
1563  简单
1564  博弈。
1565  状态DP
1566  数学
1567  模拟
1568  大数
1569  最小割
1570  数学
1571  最段路
1572  搜索
1573  数学
1574  DP
1575  2分
1576  数论
1577  模拟,处理精度
1579  记忆化
1580  DP
1582  搜索
1583  模拟
1584  搜索
1585 
1586
1587  简单题目
1591  模拟
1592  简单
1593  数学
1594  数学
1595  图论
1596  图论
1597  图论
1598  图论
1599  图论

 

字符(串)输入的方式

学C++的时候,这几个输入函数弄的有点迷糊;这里做个小结,为了自己复习,也希望对后来者能有所帮助,如果有差错的地方还请各位多多指教(本文所 有程序均通过VC 6.0运行)转载请保留作者信息;
1、cin
1、cin.get()
2、cin.getline()
3、getline()
4、gets()
5、getchar()

 

1、cin>>          

用法1:最基本,也是最常用的用法,输入一个数字:

#include <iostream>
using namespace std;
main ()
{
int a,b;
cin>>a>>b;
cout<<a+b<<endl;
}

输入:2[回车]3[回车]
输出:5

用法2:接受一个字符串,遇“空格”、“TAB”、“回车”都结束

#include <iostream>
using namespace std;
main ()
{
char a[20];
cin>>a;
cout<<a<<endl;
}

输入:jkljkljkl
输出:jkljkljkl

输入:jkljkl jkljkl       //遇空格结束
输出:jkljkl

 

2、cin.get()

 

用法1: cin.get(字符变量名)可以用来接收字符

#include <iostream>
using namespace std;
main ()
{
char ch;
ch=cin.get();               //或者cin.get(ch);
cout<<ch<<endl;
}

输入:jljkljkl
输出:j

用法2:cin.get(字符数组名,接收字符数目)用来接收一行字符串,可以接收空格

#include <iostream>
using namespace std;
main ()
{
char a[20];
cin.get(a,20);
cout<<a<<endl;
}

输入:jkl jkl jkl
输出:jkl jkl jkl

输入:abcdeabcdeabcdeabcdeabcde (输入25个字符)
输出:abcdeabcdeabcdeabcd              (接收19个字符+1个'\0')

用法3:cin.get(无参数)没有参数主要是用于舍弃输入流中的不需要的字符,或者舍弃回车,弥 补cin.get(字符数组名,接收字符数目)的不足.

这个我还不知道怎么用,知道的前辈请赐教;

 

3、cin.getline()   // 接受一个字符串,可以接收空格并输出

#include <iostream>
using namespace std;
main ()
{
char m[20];
cin.getline(m,5);
cout<<m<<endl;
}

输入:jkljkljkl
输出:jklj

接受5个字符到m中,其中最后一个为'\0',所以只看到4个字符输出;

如果把5改成20:
输入:jkljkljkl
输出:jkljkljkl

输入:jklf fjlsjf fjsdklf
输出:jklf fjlsjf fjsdklf

//延伸:
//cin.getline()实际上有三个参数,cin.getline(接受字符串的看哦那间m,接受个数5,结束字符)
//当第三个参数省略时,系统默认为'\0'
//如果将例子中cin.getline()改为cin.getline(m,5,'a');当输入jlkjkljkl时输出jklj,输入 jkaljkljkl时,输出jk

当用在多维数组中的时候,也可以用cin.getline(m[i],20)之类的用法:

#include<iostream>
#include<string>
using namespace std;

main ()
{
char m[3][20];
for(int i=0;i<3;i++)
{
cout<<"\n请输入第"<<i+1<<"个字符串:"<<endl;
cin.getline(m[i],20);
}

cout<<endl;
for(int j=0;j<3;j++)
cout<<"输出m["<<j<<"]的值:"<<m[j]<<endl;

}

请输入第1个字符串:
kskr1

请输入第2个字符串:
kskr2

请输入第3个字符串:
kskr3

输出m[0]的值:kskr1
输出m[1]的值:kskr2
输出m[2]的值:kskr3

 

4、getline()     // 接受一个字符串,可以接收空格并输出,需包含 “#include<string>”

#include<iostream>
#include<string>
using namespace std;
main ()
{
string str;
getline(cin,str);
cout<<str<<endl;
}

输入:jkljkljkl
输出:jkljkljkl

输入:jkl jfksldfj jklsjfl
输出:jkl jfksldfj jklsjfl

和cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两 个函数

 

5、gets()        // 接受一个字符串,可以接收空格并输出,需包含“#include<string>”

#include<iostream>
#include<string>
using namespace std;
main ()
{
char m[20];
gets(m);                       //不能写成m=gets();
cout<<m<<endl;
}

输入:jkljkljkl
输出:jkljkljkl

输入:jkl jkl jkl
输出:jkl jkl jkl

类似cin.getline()里面的一个例子,gets()同样可以用在多维数组里面:

#include<iostream>
#include<string>
using namespace std;

main ()
{
char m[3][20];
for(int i=0;i<3;i++)
{
cout<<"\n请输入第"<<i+1<<"个字符串:"<<endl;
gets(m[i]);
}

cout<<endl;
for(int j=0;j<3;j++)
cout<<"输出m["<<j<<"]的值:"<<m[j]<<endl;

}

请输入第1个字符串:
kskr1

请输入第2个字符串:
kskr2

请输入第3个字符串:
kskr3

输出m[0]的值:kskr1
输出m[1]的值:kskr2
输出m[2]的值:kskr3

自我感觉gets()和cin.getline()的用法很类似,只不过cin.getline()多一个参数罢了;

这里顺带说明一下,对于本文中的这个kskr1,kskr2,kskr3的例子,对于cin>>也可以适用,原因是这里输入的没有空 格,如果输入了空格,比如“ks kr jkl[回车]”那么cin就会已经接收到3个字符串,“ks,kr,jkl”;再如“kskr 1[回车]kskr 2[回车]”,那么则接收“kskr,1,kskr”;这不是我们所要的结果!而cin.getline()和gets()因为可以接收空格,所以不会产 生这个错误;

 

6、getchar()   //接受一个字符,需包含#include<string>”

#include<iostream>
#include<string>
using namespace std;
main ()
{
char ch;
ch=getchar();                        //不能写成getchar(ch);
cout<<ch<<endl;
}

输入:jkljkljkl
输出:j

//getchar()是C语言的函数,C++也可以兼容,但是尽量不用或少用;

HDU 2544最短路

#include<iostream>
using namespace std;

#define max 0x70ffffff
int map[105][105];
int visit[105];
int dis[105];

int main()
{
    int n, m, a, b, c;
    int i, j, k;
    int min;
    while ( scanf("%d%d", &n, &m) && !( n ==0 && m == 0) ) {
        for ( i = 1; i <= n; i++ ) {
            for ( j = 0; j <= n; j++ )
                map[i][j] = max;
            visit[i] = 0;
        }
        for ( i = 0; i < m; i++ ) {
            scanf( "%d%d%d", &a, &b, &c );
            map[a][b] = map[b][a] = c;
        }
        for ( i = 1; i <= m; i++ )
            dis[i] = map[1][i];
        visit[1] = 1;
        dis[1] = 0;
        for ( i = 1; i <= m; i++ ) {
            min = max;
            for ( j = 1; j <= m; j++ ) {
                if ( dis[j] < min && !visit[j] ) {
                    min = dis[j];
                    k = j;
                }
            }
            if ( min == max ) break;
            visit[k] = 1;
            for( j = 1; j <= n; j++ ) {
                  if( min + map[k][j] < dis[j] && !visit[j] )
                      dis[j] = min + map[k][j];
            }
        }
        printf("%d\n", dis[n]);
    }

    return 0;
}

hdu 2564词组缩写

刚开始用string来输入,发现不对,string 必须输入两个'\n', 或连续输入两个字符串,才能输出第一个字符串……还有输入需要放进while(1)

#include<iostream>
#include<string>
using namespace std;

int isupper( char c){
    if ( c >= 'A' && c <= 'Z' ) return 1;
    return 0;
}

int main()
{
    int t;
    scanf("%d%*c",&t);
    while(t--)
    {
        char qian,hou;
        while( 1 ) {
            qian = getchar();
            if( qian != ' ' ) {
                if( isupper(qian) ) putchar( qian );
                else putchar(qian-32);
                break;
            }
        }
        while( 1 ) {
            hou = getchar();
            if( hou == 10 ) break;
            if( qian == ' ' && hou != ' ' ) {
                if( isupper(hou) ) putchar(hou);
                else putchar( hou - 32 );
            }
            qian = hou;
        }
        putchar(10);
    }
    return 0;
}


N皇后问题(位运算)

关于N皇后问题高效试探回溯算法的分析 

// N Queens Problem
// 试探-回溯算法,递归实现

// sum用来记录皇后放置成功的不同布局数;upperlim用来标记所有列都已经放置好了皇后。
long sum = 0, upperlim = 1;     

// 试探算法从最右边的列开始。
void test(long row, long ld, long rd) 。
{
   if (row != upperlim)
   {
     // row,ld,rd进行“或”运算,求得所有可以放置皇后的列,对应位为0,
     // 然后再取反后“与”上全1的数,来求得当前所有可以放置皇后的位置,对应列改为1。
     // 也就是求取当前哪些列可以放置皇后。
     long pos = upperlim & ~(row | ld | rd); 
     while (pos) // 0 -- 皇后没有地方可放,回溯。
     {
        // 拷贝pos最右边为1的bit,其余bit置0。
        // 也就是取得可以放皇后的最右边的列。
        long p = pos & -pos;                                              

        // 将pos最右边为1的bit清零。
        // 也就是为获取下一次的最右可用列使用做准备,
        // 程序将来会回溯到这个位置继续试探。
        pos -= p;                           

        // row + p,将当前列置1,表示记录这次皇后放置的列。
        // (ld + p) << 1,标记当前皇后左边相邻的列不允许下一个皇后放置。
        // (ld + p) >> 1,标记当前皇后右边相邻的列不允许下一个皇后放置。
        // 此处的移位操作实际上是记录对角线上的限制,只是因为问题都化归
        // 到一行网格上来解决,所以表示为列的限制就可以了。显然,随着移位
        // 在每次选择列之前进行,原来N×N网格中某个已放置的皇后针对其对角线
        // 上产生的限制都被记录下来了。
        test(row + p, (ld + p) << 1, (rd + p) >> 1);                              
       }
   }
   else   
   {
       // row的所有位都为1,即找到了一个成功的布局,回溯。
       sum++;
   }
}

int main(int argc, char *argv[])
{
   time_t tm;
   int n = 16;

   if (argc != 1)
   n = atoi(argv[1]);
   tm = time(0);

   // 因为整型数的限制,最大只能32位,
   // 如果想处理N大于32的皇后问题,需要
   // 用bitset数据结构进行存储。
   if ((n < 1) || (n > 32))                 
   {
   printf(" 只能计算1-32之间\n");
   exit(-1);
   }
   printf("%d 皇后\n", n);

   // N个皇后只需N位存储,N列中某列有皇后则对应bit置1。
   upperlim = (upperlim << n) - 1;         

   test(0, 0, 0);
   printf("共有%ld种排列, 计算时间%d秒 \n", sum, (int) (time(0) - tm));
}

上述代码容易看懂,但我觉得核心的是在针对试探-回溯算法所用的数据结构的设计上。
程序采用了递归,也就是借用了编译系统提供的自动回溯功 能。

算法的核心:使用bit数组来代替以前由int或者bool数组来存储当前格子被占用或者说可用信息,从这

可以看出N个皇后对应需要N位表示。
巧妙之处在于:以前我们需要在一个N*N正方形的网格中挪动皇后来进行试探回溯,每走一步都要观察

和记录一个格子前后左右对角线上格子的信息;采用bit位进行信息存储的话,就可以只在一行格子也

就是(1行×N列)个格子中进行试探回溯即可,对角线上的限制被化归为列上的限制。
程序中主要需要下面三个bit数组,每位对应网格的一 列,在C中就是取一个整形数的某部分连续位即可


row用来记录当前哪些列上的位置不可用,也就是哪些列被皇后占用,对应为1。
ld,rd同样也是记录当前哪些列位置不可用,但 是不表示被皇后占用,而是表示会被已有皇后在对角线

上吃掉的位置。这三个位数组进行“或”操作后就是表示当前还有哪些位置可以放置新的皇后,对应0

的位置可放新的皇后。如下图所示的8皇后问题求解得第一步:
row:          [ ][ ][ ][ ][ ][ ][ ][*]
ld:           [ ][ ][ ][ ][ ][ ][*][ ]
rd:           [ ][ ][ ][ ][ ][ ][ ][ ]
--------------------------------------
row|ld|rd:    [ ][ ][ ][ ][ ][ ][*][*]
所有下一个位置的试探过程都是通过位操作来实现的,这是借用了C语言的好处, 详见代码注释。

关于此算法,如果考虑N×N棋盘的对称性,对于大N来说仍能较大地提升效率!

N皇后问题(很快,保存下)

   1. import java.util.Calendar; 
   2.  
   3. public class Queen { 
   4.  
   5. public static int sum = 0, upperlimit = 1; 
   6.  
   7. public static void compute(int row, int ld, int rd); { 
   8.  
   9. if (row != upperlimit); { 
  10. int pos = upperlimit & ~(row | ld | rd);
  11. while (pos != 0); { 
  12.  
  13. int p = pos & -pos; 
  14. pos -= p; 
  15. compute(row + p, (ld + p); << 1, (rd + p); >> 1); 
  16. } 
  17.  
  18. } else 
  19. sum++; 
  20. } 
  21.  
  22. public static void main(String[] args); { 
  23. Calendar start; 
  24. int n = 8; 
  25.  
  26. if (args.length > 0); 
  27. n = Integer.parseInt(args[0]);
  28. start = Calendar.getInstance();
  29. if ((n < 1); || (n > 32);); { 
  30. System.out.println(" 只能计算1-32之间\n");
  31. return; 
  32. } 
  33. System.out.println(n + " 皇后\n");
  34. upperlimit = (upperlimit << n); - 1; 
  35. compute(0, 0, 0);; 
  36. System.out.println("共有" 
  37. + sum 
  38. + "种排列, 计算时间" 
  39. + (Calendar.getInstance();.getTimeInMillis(); - start 
  40. .getTimeInMillis();); / 1000 + "秒 \n");
  41. } 
  42.  
  43. } 




Host by is-Programmer.com | Power by Chito 1.3.3 beta
Butterfly Theme | Design: HRS Hersteller of mobile Hundeschule.