奥赛经典电子版见文章最下。
这是例题3-4的测试数据。
http://download.csdn.net/detail/occupiedcsdn/9330733
这道题的讲解感觉很巧妙,具体是什么意思呢,就是先把这些数存到一个队列w中,然后排序,此时y是空队列。
每次把w和y中最小的两个拿出来,合并,放到y中,这样得到的y一定也有序,最后w空了时,将y中的数复制至w中,重复操作,最后当w,y中仅一个数时,停止执行。
至于每次怎么取两个队列中最小的,就是先比较两个队列的队首元素,将较小的出队,保存起来,在比较队首元素,较小的出队,保存起来,这样就可以将二者做和了。
代码如下:
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
int s[30000];
queue<int> w,y;
bool popw();
int main()
{
freopen("fruit_data.in","r",stdin);
freopen("fruit_data.out","w",stdout);
int n = 0, cnt = 0;
scanf("%d", &n);
for(int i = 1;i <= n;i++)
scanf("%d", &s[i]);
sort(s+1, s+n+1);
for(int i = 1;i <= n;i++) w.push(s[i]);
while(1)
{
while(!w.empty())
{
int a, b;
if(popw())
{
a = w.front();
w.pop();
}
else
{
a = y.front();
y.pop();
}
if(popw())
{
b = w.front();
w.pop();
}
else
{
b = y.front();
y.pop();
}
y.push(a+b);
cnt += a+b;
}
w.push(y.front());
y.pop();
if(y.empty()) break;
else
{
while(!y.empty())
{
w.push(y.front());
y.pop();
}
}
}
printf("%d", cnt);
//getchar();getchar();
return 0;
}
bool popw()
{
if(y.empty()) return true;
if(w.empty()) return false;
if(w.front() < y.front()) return true;
else return false;
}
这是例题3-5的代码,不多说了,BFS。
只测了几组数据,应该没啥问题,如果大家发现问题,请广泛指出,谢谢。
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 100, maxs = 2147483647;
bool m[maxn][maxn];//save the map
int check[maxn][maxn];//check if (x,y) has been visited
const int cx[8] = {2, 2, 1, 1, -1, -1, -2, -2};
const int cy[8] = {1, -1, 2, -2, 2, -2, 1, -1};
int n, x, y;
queue<int> qx, qy;
bool f(int);//不要忘记对是否越界判断
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Outputmyself.txt","w",stdout);
scanf("%d%d%d", &n, &x, &y);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
char c;
scanf("%c", &c);
if(c == '\n') j--;
if(c == '*') m[i][j] = false;
else if(c == '_') m[i][j] = true;
}
memset(check, -1, sizeof(check));
qx.push(x);
qy.push(y);
check[x][y] = 0;
while(!qx.empty())
{
int a = qx.front();
int b = qy.front();
qx.pop();
qy.pop();
for(int i = 0; i < 8; i++)
{
int tx = a + cx[i], ty = b + cy[i];
if(check[tx][ty] == -1 && m[tx][ty] && f(tx) && f(ty))
{
qx.push(tx);
qy.push(ty);
check[tx][ty] = check[a][b] + 1;
}
}
/*
表示之前上面那个for循环给写成这样了,还是广搜不太熟的原因啊
for(int i = 0; i < 8; i++)
for(int j = 0; j < 8; j++)
{
int tx = a + cx[i], ty = b + cy[j];
if(check[tx][ty] == -1 && m[tx][ty] && f(tx) && f(ty))
{
qx.push(tx);
qy.push(ty);
check[tx][ty] = check[a][b] + 1;
}
}
*/
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
printf("%d ",check[i][j]);
printf("\n");
}
return 0;
}
bool f(int x)
{
if(x < 1) return false;
if(x > n) return false;
return true;
}