自已花了一下午写的代码,自已也在学习程序的设计,供大家交流学习,交流才能促进学习进步!!
俄罗斯套娃奖品
伊万洛夫在比武大会上力克群雄,成为新一届“草原雄鹰”,为部落赢得了莫大荣誉。首领决定要重重奖赏,他对伊万洛夫说:“孩
子,你是知道的,面前的这片草原,南北向和东西向的道路纵横交错。现在,路口放着纯金打造的俄罗斯娃娃,重量大小不等,重的
都能装下轻的。你可以沿着道路飞奔,拾取路口的娃娃,要求是任何时刻必须是一个套娃,装好后就不能再拆开了。注意不要走重复路。”
请你为伊万洛夫规划路线,使得他能够有最大的收获。
Input:
cross.txt
输入包括多组测试用例;
每个测试用例开始是一对整数
C>
,R
表示东西向道路数,C
表示南北向道路总数;接下来R
行,每行包括C
个正整数(或0
)W[r,c]
,分别表示第r
条东西向道路与第c
条南北向道路交叉处路口放置的俄罗斯娃娃的重量(或表示没有放置娃娃)。
Output:
输出能有最大收获的路径规划。
假设1
:
cross.txt
2 7
1 2 13 6 7
12 11
14 3 4 5 8
9 10
输出:
1
2 3 4 5 6 7 8 9 10 11 12
假设2
:
cross.txt
5 5
1 16 15 14 13
2 17 24 23 12
3 18 25 22 11
4 19 20 21 10
5 6 7 8
9
输出:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
下面是我做此题的思路,欢迎大家讨论补充:
1.首先从左上角开始,比始现在是“1”, 找到可以走的邻节点,2和16都是可以走的。然后把1,2和1,16分别装入两个队列之中。之后再把
1,2和1,16这两个队列再加入一个更大的队列list的末端中。
2. 在list队列中取出其中的第一个队列,可取出1,2这个队列(取出来之后list队列中就不再含有1,2队列了)。然后把1,2这个队列的最后一个元素2取出。再找2附近的邻节点,有17,3.(1不在,因为已经走过了),分别邻节点压入这个队列的末端。然后我们有1,2,17和1,2,3这两个队列。我们再将这两个队列压入list队列的末端。
3. 重复第二步,不断取出list队列中的子队列,如果子队列再也找不到邻节点,我们可认为这是一条路径。但我们并不知道其是否为最优路径,所以此时我们还要再维护着一个最优路径。如果刚才这条子路径上能获取的重要大于最优路径的话,我们可更新该子路径为最优路径。
最后当list队列不再含有子队列时,我们已遍历了所有可走的路径。此时我们维护的最优路径就是我们所需要的结果。
下面是源码:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef struct
{
int row;
int col;
int weight;
}wawa;
typedef struct
{
int row;
int col;
}size;
// compare two struct wawa, if equal return 0
// if a> b, return a positive number
// else b>a, return a negative number
int cmp(wawa a, wawa b)
{
if(a.row == b.row && a.col == b.col) return 0;
if(a.row > b.row || (a.row==b.row && a.col > b.col)) return 1;
if(a.row < b.row || (a.row==b.row && a.col < b.col)) return -1;
}
// This function is used to read all the useful
// numbers in the text file, the path can be modified
// by users with text file in a different path
void inputAll(vector &item, size &sz)
{
ifstream in("/home/huyi/桌面/MyProgram/wawa/cross1.txt");
char buf[10];
int row, col, weight;
char ch;
int i,j;
wawa ad;
if(!in)
{
cerr<
}
in.get(buf, sizeof(buf), ' ');
row= atoi(buf); // get the total number of rows
in.getline(buf, sizeof(buf));
col= atoi(buf); // get the total number of columns
sz.row= row;
sz.col= col;
for(i=0; i< row; i++) // the whole is used to get the the row value
{ // ,the column and weight value from the text
for(j=0; j< col-1; j++) // file, then push then to a vector.
{
in.getline(buf, sizeof(buf), ' ');
ad.weight=atoi(buf);
ad.row= i;
ad.col= j;
item.push_back(ad);
}
in.getline(buf, sizeof(buf));
ad.weight=atoi(buf);
ad.col=j;
item.push_back(ad);
}
}
// in this function, we donot know the weight value in
// the "neighbor" wawa struct, so I write this function in
// order to get the weight value by iterating the vector
void getWeight(vector &item, wawa &neighbor)
{
for(int i=0; i< item.size(); i++)
{
if(cmp(item[i], neighbor) == 0)
neighbor.weight= item[i].weight;
}
}
// check if the "neighbor" wawa struct is in the list
// if it is in, return true;
// else return false
bool checkList(list &wawaPicked, wawa &neighbor)
{
list::const_iterator pos;
for(pos= wawaPicked.begin(); pos!= wawaPicked.end(); ++pos)
{
if(cmp(*pos, neighbor) == 0) return true;
}
return false;
}
// This function is used to find the neighbors of a particular
// waawa struct. and then put all the neighbor wawa struct into
// a vector called "neighbors"
void findNeighbors(list &wawaPicked, wawa &last, vector &neighbors, size &sz, vector &item)
{
wawa ngbor;
if(last.row< sz.row-1)
{
ngbor.row = last.row+ 1;
ngbor.col = last.col;
getWeight(item, ngbor);
if(!checkList(wawaPicked, ngbor) && ngbor.weight> last.weight)
neighbors.push_back(ngbor);
}
if(last.row> 0)
{
ngbor.row= last.row- 1;
ngbor.col= last.col;
getWeight(item, ngbor);
if(!checkList(wawaPicked, ngbor) && ngbor.weight> last.weight)
neighbors.push_back(ngbor);
}
if(last.col< sz.col-1)
{
ngbor.row= last.row;
ngbor.col= last.col+1;
getWeight(item, ngbor);
if(!checkList(wawaPicked, ngbor) && ngbor.weight> last.weight)
neighbors.push_back(ngbor);
}
if(last.col> 0)
{
ngbor.row= last.row;
ngbor.col= last.col-1;
getWeight(item, ngbor);
if(!checkList(wawaPicked, ngbor) && ngbor.weight> last.weight)
neighbors.push_back(ngbor);
}
}
// compute the whole weight of a list containing wawa struct.
// and add all the weight. then return the sum
int computeWeight(list &listTmp)
{
int weight;
list::iterator pos;
for(pos= listTmp.begin(); pos!= listTmp.end(); ++pos)
weight+= pos->weight;
return weight;
}
// This is the core function of find the best way which has the biggest
// weight value. in this function I use a breadth-first-search algorithm
// the "carriedWawa" list is used to store all the possible paths.
// and the "finalPath" is used to store the path which currently has the
// biggest weight
bool findBestWay(vector &item, list > &carriedWawa, size &sz, list &finalPath, int &maxWeight)
{
if(carriedWawa.empty()) return true; // if the whole paths we have searched, we can return and we has found the best way
list listTmp= carriedWawa.front();
carriedWawa.pop_front();
wawa wawaTmp= listTmp.back();
vector neighbors;
int weight=0;
findNeighbors(listTmp, wawaTmp,neighbors, sz, item); // find all neighbors which we has gone to before
if(neighbors.size() == 0) // if the neighbors doesnot exist, it means we get a new path
{ // then we compare to the "finalPath", if it has bigger weight
weight= computeWeight(listTmp); // than "finalPath", then we update "finalPath" to the current
if(weight> maxWeight) // path
{
finalPath.clear();
maxWeight= weight;
finalPath= listTmp;
}
return false;
}
for(int i=0; i< neighbors.size(); i++)
{
listTmp.push_back(neighbors[i]);
carriedWawa.push_back(listTmp);
listTmp.pop_back();
}
return false;
}
// This is the main function, with all the initial values,
// I think it's a bit complicate. if you really want to figure
// out what is going on in the whole program, findBestWay function
// is the most critical one.
int main()
{
list carriedWawa;
list finalPath;
list > init;
vector item;
int maxWeight= 0;
size sz;
inputAll(item, sz);
carriedWawa.push_back(item[0]);
init.push_back(carriedWawa);
while(!findBestWay(item, init, sz, finalPath, maxWeight));
cout<
list::iterator pos;
for(pos= finalPath.begin(); pos!= finalPath.end(); ++pos)
cout<weight<
cout<
}