海贼王之伟大航路
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define MAXN 20
#define INFINITE 1<<30
int N;
int graph[MAXN][MAXN];
typedef pair<int, int> Path_End;
map<Path_End, int> dp;
//queue<Path_End> q;
int bestTime;
void dfs(int path, int i, int sum)
{
if (sum >= bestTime)
return;
if (i == N)
{
if (path != (1 << (N + 1)) - 1 - 1)
return;
bestTime = min(bestTime, sum);
if (dp.count({ path,i }))
{
if (dp[{path, i}] <= sum)
return;
else
dp[{path, i}] = sum;
}
else
{
dp.insert(pair<Path_End, int>({ path,i }, sum));
}
return;
}
if (dp.count({ path,i }))
{
if (dp[{path, i}] <= sum)
return;
else
dp[{path, i}] = sum;
}
else
{
dp.insert(pair<Path_End, int>({ path,i }, sum));
}
for (int j = 1; j <= N; j++)
{
if (i != j)
{
if (!(path & (1 << j)))
{
int newPath = path;
newPath = (newPath | (1 << j));
dfs(newPath, j, sum + graph[i][j]);
}
}
}
}
//void bfs()
//{
// q.push({ 2,1 });
//
// while (!q.empty())
// {
// Path_End pathend = q.front();
// q.pop();
//
// for (int j = 1; j <= N; j++)
// {
// if (j != pathend.second)
// {
// if (!(pathend.first & (1 << j)))
// {
// int newPath = pathend.first;
//
//
//
// newPath = (newPath | (1 << j));
// //dfs(newPath, j, sum + graph[i][j]);
//
// if (dp.count({ newPath,j }))
// {
// if (dp[{newPath, j}] > dp[{pathend.first, pathend.second}] + graph[pathend.second][j])
// dp[{newPath, j}] = dp[{pathend.first, pathend.second}] + graph[pathend.second][j];
// }
// else
// {
// dp.insert(pair<Path_End, int>({ newPath,j }, dp[{pathend.first, pathend.second}] + graph[pathend.second][j]));
// q.push({ newPath,j });
// }
// }
//
//
// }
// }
//
// }
//}
int main()
{
{
bestTime = INFINITE;
scanf("%d", &N);
dp.clear();
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
scanf("%d", &graph[i][j]);
}
}
dfs(2, 1, 0);
//bfs();
printf("%d\n", dp[{(1 << (N + 1)) - 1 - 1, N}]);
}
}
蛋糕
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include <math.h>
using namespace std;
#define MAXN 30
int n, m;
int minArea = 1 << 30;
int area = 0;
int minV[MAXN];
int minA[MAXN];
int maxV(int level, int r, int h)
{
int sum = 0;
for (int i = level; i >= 1; i--)
{
sum += r*r*h;
r--;
h--;
}
return sum;
}
void dfs(int level, int r, int h, int v)
{
if (level == 0)
{
if (v == 0)
minArea = min(minArea, area);
return;
}
if (v <= 0)
return;
if (v < minV[level])
return;
if (v>maxV(level, r, h))
return;
if (area >= minArea)
return;
if (area + minA[level] >= minArea)
return;
for (int rr = r; rr >= level; rr--)//当前层的半径
{
if (level == m)
area = rr*rr;
for (int hh = h; hh >= level; hh--)//当前层的高度
{
area += 2 * rr*hh;
dfs(level - 1, rr - 1, hh - 1, v - rr*rr*hh);
area -= 2 * rr*hh;
}
}
}
int main()
{
scanf("%d%d", &n, &m);
minV[0] = 0;
minA[0] = 0;
for (int i = 1; i <= m; i++)
{
minV[i] = minV[i - 1] + i*i*i;
minA[i] = minA[i - 1] + 2 * i*i;
}
if (minV[m] > n)
{
printf("0\n");
return 0;
}
int maxR = sqrt((double)(n - minV[m - 1]) / m) + 1;
int maxH = (double)(n - minV[m - 1]) / (m*m) + 1;
dfs(m, maxR, maxH, n);
if (minArea == 1 << 30)
printf("0\n");
else
printf("%d\n", minArea);
}
棋盘问题
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
#define MAXN 12
#define INFINITE 1<<30
int n, k;
int c;
int chess[MAXN][MAXN];
int position[MAXN];
void search(int cur,int chessCnt)//cur表示行
{
if (chessCnt==k)
{
c++;
return;
}
if(cur>n)
return;
if(n-cur+1<k-chessCnt)
return;
for (int i = 1; i <= n; i++)//遍历列,选择在这行下棋子
{
if (chess[cur][i])
{
position[cur] = i;//cur行,i列
int ok = 1;
for (int j = 1; j<cur; j++)
{
if (position[j] == i )
{
ok = 0;
break;
}
}
if (ok)
{
search(cur + 1,chessCnt+1 );
}
}
}
position[cur] = 0;//选择不下棋子
search(cur + 1,chessCnt);
}
int main()
{
while (scanf("%d%d", &n, &k) == 2)
{
if (n == -1)
return 0;
c = 0;
memset(chess, 0, sizeof(chess));
memset(position, 0, sizeof(position));
char str[MAXN];
for (int i = 1; i <= n; i++)
{
scanf("%s", str);
for (int j = 0; j<n; j++)
{
if (str[j] == '#')
{
chess[i][j + 1] = 1;
}
}
}
search(1,0);
printf("%d\n", c);
}
}
roads POJ1724
#include <iostream>
#include <vector>
#include <cstring>
#include<algorithm>
using namespace std;
#define MAXN 110
#define INFINITE 1<<30
struct Road
{
int d, L, t;
};
vector<vector<Road> > cityMap(110); //邻接表。 cityMap[i]是从点i有路连到的城市集合
int minLen = 1 << 30; //当前找到的最优路径的长度
int totalLen; //正在走的路径的长度
int totalCost; //正在走的路径的花销
int visited[110]; //城市是否已经走过的标记
int minL[110][10100]; //minL[i][j]表示从1到i点的,花销为j的最短路的长度
int K, N, R;
void dfs(int s)
{
if (s == N)
{
minLen = min(minLen, totalLen);
return;
}
for (int i = 0; i < cityMap[s].size(); i++)
{
int d = cityMap[s][i].d;
{
if (!visited[d])
{
int cost = totalCost + cityMap[s][i].t;
if (cost>K)
continue;
if (totalLen + cityMap[s][i].L >= minLen ||
totalLen + cityMap[s][i].L >= minL[d][cost])
continue;
totalLen += cityMap[s][i].L;
totalCost += cityMap[s][i].t;
minL[d][cost] = totalLen;
visited[d] = 1;
dfs(d);
visited[d] = 0;
totalLen -= cityMap[s][i].L;
totalCost -= cityMap[s][i].t;
}
}
}
}
int main()
{
cin >> K >> N >> R;
for (int i = 1; i <= R; i++)
{
int s;
Road r;
cin >> s >> r.d >> r.L >> r.t;
if (s != r.d)
{
cityMap[s].push_back(r);
}
}
for (int i = 0; i<110; i++)
{
for (int j = 0; j<10100; j++)
minL[i][j] = INFINITE;
}
memset(visited, 0, sizeof(visited));
minLen = INFINITE;
totalCost = totalLen = 0;
visited[1] = 1;
dfs(1);
if (minLen < (1 << 30))
cout << minLen << endl;
else
cout << "-1" << endl;
}
迷宫问题 (POJ3984)
#include<stdio.h>
#include<queue>
#include<string.h>
#include<stack>
using namespace std;
int graph[10][10];
int front;
int rear;
int visited[10][10];
struct Node
{
int x;
int y;
int father;
Node()
{
}
Node(int _x, int _y, int _father) :x(_x), y(_y), father(_father)
{
}
};
Node q[2500];
int isPosLegal(int x, int y)
{
return (x >= 1 && x <= 5 && y >= 1 && y <= 5);
}
int main()
{
rear = 0;
front = 1;
memset(visited, 0, sizeof(visited));
for (int i = 1; i <= 5; i++)
{
for (int j = 1; j <= 5; j++)
{
scanf("%d", &graph[i][j]);
}
}
q[++rear] = Node(1, 1, 0);
visited[1][1] = 1;
int ok = 0;
while (rear != front - 1)
{
Node n = q[front];
int father = front;
if (n.x == 5 && n.y == 5)
{
ok = 1;
break;
}
front++;
if (isPosLegal(n.x + 1, n.y) && visited[n.x + 1][n.y] == 0 && graph[n.x + 1][n.y]==0)
{
q[++rear] = Node(n.x + 1, n.y, father);
visited[n.x + 1][n.y] = 1;
}
if (isPosLegal(n.x - 1, n.y) && visited[n.x - 1][n.y] == 0 && graph[n.x - 1][n.y] == 0)
{
q[++rear] = Node(n.x - 1, n.y, father);
visited[n.x - 1][n.y] = 1;
}
if (isPosLegal(n.x, n.y + 1) && visited[n.x][n.y + 1] == 0 && graph[n.x ][n.y+1] == 0)
{
q[++rear] = Node(n.x, n.y + 1, father);
visited[n.x ][n.y+1] = 1;
}
if (isPosLegal(n.x, n.y - 1) && visited[n.x][n.y - 1] == 0 && graph[n.x ][n.y-1] == 0)
{
q[++rear] = Node(n.x, n.y - 1, father);
visited[n.x ][n.y-1] = 1;
}
}
stack<int> s;
if (ok)
{
while (front)
{
s.push(front);
front = q[front].father;
}
int pos;
while (!s.empty())
{
pos = s.top();
s.pop();
printf("(%d, %d)\n", q[pos].x-1, q[pos].y-1);
}
}
}
鸣人和佐助
#include<stdio.h>
#include<queue>
#include<string.h>
#include<stack>
using namespace std;
struct Node
{
int x;
int y;
int chakela;
int time;
Node()
{
}
Node(int _x, int _y, int _chakela, int _time) :x(_x), y(_y), chakela(_chakela), time(_time)
{
}
};
int M, N, T;
int record[210][210][15];
int graph[210][210];
int end_x, end_y;
int beg_x, beg_y;
int isFind = 0;
int isPosLegal(int x, int y)
{
return (x >= 1 && x <= M && y >= 1 && y <= N);
}
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
void bfs()
{
queue<Node> q;
q.push(Node(beg_x, beg_y, T, 0));
while (!q.empty())
{
Node n = q.front();
q.pop();
if (n.x == end_x && n.y == end_y)
{
printf("%d\n", n.time);
isFind = 1;
return;
}
else
{
for (int i = 0; i<4; i++)
{
int r = n.x + dx[i];
int c = n.y + dy[i];
if (isPosLegal(r, c) )
{
if (graph[r][c] == 3 || graph[r][c] == 2)
{
if (record[r][c][n.chakela]>n.time + 1)
{
q.push(Node(r, c, n.chakela, n.time + 1));
record[r][c][n.chakela] = n.time + 1;
}
}
else if (graph[r][c] == 4 && n.chakela>0)
{
if (record[r][c][n.chakela - 1] > n.time + 1)
{
q.push(Node(r, c, n.chakela - 1, n.time + 1));
record[r][c][n.chakela - 1] = n.time + 1;
}
}
}
}
}
}
}
int main()
{
for (int i = 0; i < 210; i++)
for (int j = 0; j < 210; j++)
for (int k = 0; k < 15; k++)
record[i][j][k] = 1 << 30;
scanf("%d%d%d", &M, &N, &T);
char str[210];
for (int i = 1; i <= M; i++)
{
scanf("%s", str);
for (int j = 1; j <= N; j++)
{
if (str[j - 1] == '@')
{
graph[i][j] = 1;
beg_x = i;
beg_y = j;
}
else if (str[j - 1] == '+')
{
graph[i][j] = 2;
end_x = i;
end_y = j;
}
else if (str[j - 1] == '*')
graph[i][j] = 3;
else if (str[j - 1] == '#')
graph[i][j] = 4;
}
}
bfs();
if (!isFind)
printf("%d\n", -1);
}
Flip Game 翻转棋盘
#include<stdio.h>
#include<queue>
#include<string.h>
#include<stack>
#include<bitset>
#include<map>
#include<set>
using namespace std;
int graph[6][6];//black 0,white 1
set<int> visited;
int isFinish(int bin)
{
int flag = 0;
for (int i = 1; i <= 16; i++)
{
if (bin & 1 << i)
{
if (flag == 0)
flag = 1;
else if (flag == 2)
return 0;
}
else
{
if (flag == 0)
flag = 2;
else if (flag == 1)
return 0;
}
}
return 1;
}
int chessToInt(int(*gra)[6])
{
int bin = 0;
for (int i = 1; i <= 4; i++)
{
for (int j = 1; j <= 4; j++)
{
if (gra[i][j] == 1)
bin = bin | (1 << ((i - 1) * 4 + j));
}
}
return bin;
}
struct Node
{
int bin;
int time;
Node()
{
}
Node(int _bin, int _time) :bin(_bin), time(_time)
{
}
};
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
int isPosLegal(int x, int y)
{
return (x >= 1 && x <= 4 && y >= 1 && y <= 4);
}
int main()
{
int isFind = 0;
char str[100];
for (int i = 1; i <= 4; i++)
{
scanf("%s", str);
for (int j = 1; j <= 4; j++)
{
if (str[j - 1] == 'b')
{
graph[i][j] = 0;
}
else
graph[i][j] = 1;
}
}
queue<Node> q;
int inputBin;
inputBin = chessToInt(graph);
q.push(Node(inputBin, 0));
visited.insert(inputBin);
while (!q.empty())
{
Node node = q.front();
q.pop();
if (isFinish(node.bin))
{
printf("%d\n", node.time);
isFind = 1;
break;
}
int newBin;
for (int i = 1; i <= 4; i++)
{
for (int j = 1; j <= 4; j++)
{
newBin = node.bin;
newBin = newBin ^ (1 << ((i - 1) * 4 + j));
for (int k = 0; k < 4; k++)
{
int r, c;
r = i + dx[k];
c = j + dy[k];
if (isPosLegal(r, c))
{
newBin = newBin ^ (1 << ((r - 1) * 4 + c));
}
}
if (!visited.count(newBin))
{
visited.insert({ newBin,node.time + 1 });
q.push(Node(newBin, node.time + 1));
}
}
}
}
if (isFind == 0)
printf("Impossible");
}
八数码POJ1077
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;
char visited[362880 / 8 + 30];
int chess[15];
int goalstutas;
int startstutas;
int isfind;
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
char dir[] = "udlr";
struct Node
{
int status;
char from;
int pos;
int father;
Node()
{
}
Node(int _status, char _from, int _pos, int _father) :status(_status), from(_from), pos(_pos), father(_father)
{
}
};
Node record[100000000];
int head;
int tail;
int jiecheng(int n)
{
int ans = 1;
while (n)
{
ans *= n;
n--;
}
return ans;
}
int chessToInt()
{
int used[15];
memset(used, 0, sizeof(used));
int sum = 0;
for (int i = 1; i <= 8; i++)
{
int cnt = 0;
for (int j = 1; j < chess[i]; j++)
{
if (used[j] == 0)
cnt++;
}
sum += (cnt*jiecheng(9 - i));
used[chess[i]] = 1;
}
return sum;
}
void intToChess(int num)
{
int used[15];
memset(used, 0, sizeof(used));
int sum = 0;
for (int i = 1; i <= 9; i++)
{
int j = 1;
while (j <= 9)
{
if (used[j])
{
j++;
continue;
}
sum += jiecheng(9 - i);
if (sum > num)
{
used[j] = 1;
chess[i] = j;
sum -= jiecheng(9 - i);
break;
}
j++;
}
}
}
int isLegal(int r, int c)
{
return r >= 1 && r <= 3 && c >= 1 && c <= 3;
}
void bfs()
{
while (tail + 1 != head)
{
Node n = record[head];
if (n.status == goalstutas)
{
stack<char> s;
int cur = head;
while (record[cur].father != 0)
{
s.push(record[cur].from);
cur = record[cur].father;
}
while (!s.empty())
{
printf("%c", s.top());
s.pop();
}
isfind=1;
return;
}
intToChess(n.status);
int r = (n.pos - 1) / 3 + 1;
int c = (n.pos - 1) % 3 + 1;
for (int i = 0; i < 4; i++)
{
int nx = r + dx[i];
int ny = c + dy[i];
if (!isLegal(nx, ny))
continue;
swap(chess[n.pos], chess[(nx - 1) * 3 + ny]);
int status_temp = chessToInt();
if (visited[status_temp / 8] & (1 << (status_temp % 8)))
{
swap(chess[n.pos], chess[(nx - 1) * 3 + ny]);
continue;
}
record[++tail] = Node(status_temp, dir[i], (nx - 1) * 3 + ny, head);
visited[status_temp / 8] = ((visited[status_temp / 8] | (1 << (status_temp % 8))));
swap(chess[n.pos], chess[(nx - 1) * 3 + ny]);
}
head++;
}
}
int main()
{
for (int i = 1; i <= 8; i++)
chess[i] = i + 1;
chess[9] = 1;
goalstutas = chessToInt();
char c;
int pos;
for (int i = 1; i <= 9; i++)
{
while ((c = getchar()) == ' ')
;
if (c != 'x')
chess[i] = (int)(c - '0') + 1;
else
{
chess[i] = 1;
pos = i;
}
}
startstutas = chessToInt();
head = 1;
tail = 0;
record[++tail] = Node(startstutas, '#', pos, 0);
memset(visited, 0, sizeof(visited));
isfind=0;
bfs();
if(!isfind)
printf("unsolvable");
}
八数码 双向广搜
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<bitset>
#include<map>
using namespace std;
int chess[15];
int goalstutas;
int startstutas;
int startPos;
int isfind;
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };
char dir[] = "udlr";
struct Node
{
int status;
char from;
int pos;
int fatherstatus;
Node()
{
}
Node(int _status, char _from, int _pos, int _fatherstatus) :status(_status), from(_from), pos(_pos), fatherstatus(_fatherstatus)
{
}
};
map<int, Node> record[2];
queue<Node> q[2];
int jiecheng(int n)
{
int ans = 1;
while (n)
{
ans *= n;
n--;
}
return ans;
}
int chessToInt()
{
int used[15];
memset(used, 0, sizeof(used));
int sum = 0;
for (int i = 1; i <= 8; i++)
{
int cnt = 0;
for (int j = 1; j < chess[i]; j++)
{
if (used[j] == 0)
cnt++;
}
sum += (cnt*jiecheng(9 - i));
used[chess[i]] = 1;
}
return sum;
}
void intToChess(int num)
{
int used[15];
memset(used, 0, sizeof(used));
int sum = 0;
for (int i = 1; i <= 9; i++)
{
int j = 1;
while (j <= 9)
{
if (used[j])
{
j++;
continue;
}
sum += jiecheng(9 - i);
if (sum > num)
{
used[j] = 1;
chess[i] = j;
sum -= jiecheng(9 - i);
break;
}
j++;
}
}
}
void show(int num)
{
int used[15];
memset(used, 0, sizeof(used));
int sum = 0;
int chess2[15];
for (int i = 1; i <= 9; i++)
{
int j = 1;
while (j <= 9)
{
if (used[j])
{
j++;
continue;
}
sum += jiecheng(9 - i);
if (sum > num)
{
used[j] = 1;
chess2[i] = j;
sum -= jiecheng(9 - i);
break;
}
j++;
}
}
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
printf("%d ", chess2[(i - 1) * 3 + j]);
}
printf("\n");
}
printf("\n");
}
int isLegal(int r, int c)
{
return r >= 1 && r <= 3 && c >= 1 && c <= 3;
}
char reserveMove(char c)
{
switch (c)
{
case 'l':return 'r';
case 'u':return 'd';
case 'r':return 'l';
case 'd':return 'u';
default:
break;
}
}
int expand(int which)
{
int which2 = (which == 0) ? 1 : 0;
Node n = q[which].front();
q[which].pop();
if (record[which2].count(n.status))
{
stack<char> s;
Node temp = record[0][n.status];
while (temp.fatherstatus != -1)
{
s.push(temp.from);
temp = record[0][temp.fatherstatus];
}
while (!s.empty())
{
printf("%c", s.top());
s.pop();
}
temp = record[1][n.status];
while (temp.fatherstatus != -1)
{
printf("%c",reserveMove( temp.from));
temp = record[1][temp.fatherstatus];
}
isfind = 1;
return 1;
}
intToChess(n.status);
int r = (n.pos - 1) / 3 + 1;
int c = (n.pos - 1) % 3 + 1;
for (int i = 0; i < 4; i++)
{
int nx = r + dx[i];
int ny = c + dy[i];
if (!isLegal(nx, ny))
continue;
swap(chess[n.pos], chess[(nx - 1) * 3 + ny]);
int status_temp = chessToInt();
if (record[which].count(status_temp))
{
swap(chess[n.pos], chess[(nx - 1) * 3 + ny]);
continue;
}
Node newnode = Node(status_temp, dir[i], (nx - 1) * 3 + ny, n.status);
q[which].push(newnode);
record[which].insert({ newnode.status,newnode });
swap(chess[n.pos], chess[(nx - 1) * 3 + ny]);
}
return 0;
}
void dbfs()
{
q[0].push(Node(startstutas, '#', startPos, -1));
q[1].push(Node(goalstutas, '#', 9, -1));
record[0].insert({ startstutas,Node(startstutas, '#', startPos, -1) });
record[1].insert({ goalstutas,Node(goalstutas, '#', 9, -1) });
while (!q[0].empty() && !q[1].empty())
{
if (q[0].size() <= q[1].size())
{
if (expand(0))
return;
}
else
{
if (expand(1))
return;
}
}
while (!q[0].empty())
{
if (expand(0))
return;
}
while (!q[1].empty())
{
if (expand(1))
return;
}
}
int main()
{
for (int i = 1; i <= 8; i++)
chess[i] = i + 1;
chess[9] = 1;
goalstutas = chessToInt();
char c;
for (int i = 1; i <= 9; i++)
{
while ((c = getchar()) == ' ')
;
if (c != 'x')
chess[i] = (int)(c - '0') + 1;
else
{
chess[i] = 1;
startPos = i;
}
}
startstutas = chessToInt();
isfind = 0;
dbfs();
if (!isfind)
printf("unsolvable");
}
抓住那头牛(POJ3278)
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
#define MAXN 100010
int N, K;
struct Node
{
int pos;
int time;
Node(int _pos, int _time) :pos(_pos), time(_time)
{
}
};
queue<Node> q;
int visited[MAXN];
int main()
{
scanf("%d%d", &N, &K);
memset(visited, 0, sizeof(visited));
q.push(Node(N, 0));
visited[N] = 1;
while (!q.empty())
{
Node n = q.front();
q.pop();
int pos = n.pos;
int time = n.time;
if (pos == K)
{
printf("%d", time);
return 0;
}
if (pos - 1 >= 0 && visited[pos - 1] == 0)
{
q.push(Node(pos - 1, time + 1));
visited[pos - 1] = 1;
}
if (pos + 1 <= 100010 && visited[pos + 1] == 0)
{
q.push(Node(pos + 1, time + 1));
visited[pos + 1] = 1;
}
if (pos * 2 <= 100010 && pos * 2 >= 0 && visited[pos * 2] == 0)
{
q.push(Node(pos * 2, time + 1));
visited[pos * 2] = 1;
}
}
}