第一题:度度熊就是要第一个出场
贴图不方便, 完整题目见这里
我的思路:
1,从下向上,找第一名的路径,把横线段做标记1,没有横线段的地方添加横线段出来,标记2
2,从上向下,找第K名(即度度熊的位置)的路径,遇到有标记的即表示本身就是第一(标记1),或加线段后可以是第一(标记2)
代码如下, 测试用例可以通过, 又做了几个简单的测试
// 2012 百度之星 初赛 第一场 题A:度度熊就是要第一个出场 #include <iostream> #include <vector> #include <algorithm> using namespace std; typedef struct line { int elem1; int elem2; int elem3; int path; }line; //升序排序,是"<",降序排列是">"号 bool cmp(line a,line b){ return a.elem3<b.elem3; } int main() { int loop; cin>>loop; while (loop--) { int i,j,tag=0,N,M,K,max3=0,noline=0;//员工数,线段树,度度熊的位置 cin>>N>>M>>K; int tmpK = K; vector<line> array; //M条线段 line lin; for(i=0;i<M;i++) { cin>>lin.elem1>>lin.elem2>>lin.elem3; lin.path = 0; array.push_back(lin); } //按线段高低降序排列按线段高低降序排列 sort(array.begin(),array.end(),cmp); //从下向上,找第一名的路线,线段path标记为1 int firstpath = 1; int preelem3; preelem3 = 0; for (i=0;i<M;i++) { max3 = max3>array[i].elem3?max3:array[i].elem3; if (array[i].elem1==firstpath||array[i].elem2==firstpath) { noline++; //与上一个高度差 if(array[i].elem3>preelem3+1){ for (j=array[i].elem3-1;j>preelem3;j--) { lin.elem1 = firstpath; lin.elem2 = firstpath+1; lin.elem3 = j; lin.path = 2; array.push_back(lin); //往右添加横线 lin.elem1 = firstpath-1; lin.elem2 = firstpath; array.push_back(lin); //往左添加横线 } } //主轴移动到旁边一个轴上 firstpath = array[i].elem1==firstpath?array[i].elem2:array[i].elem1; array[i].path = 1; preelem3 = array[i].elem3; } } if (noline==0) { for (j=0;j<max3+1;j++) { lin.elem1 = 1; lin.elem2 = 2; lin.elem3 = j; lin.path = 2; array.push_back(lin); //往右添加横线 } } //在主轴最大值上向左右加横线 for (i=preelem3+1;i<=max3+1;i++) { lin.elem1 = firstpath; lin.elem2 = firstpath+1; lin.elem3 = i; lin.path = 2; array.push_back(lin); //往右添加横线 lin.elem1 = firstpath-1; lin.elem2 = firstpath; array.push_back(lin); //往左添加横线 } //稳定排序,使固有线段在后加线段之前 stable_sort(array.begin(),array.end(),cmp); //从上向下,找度度熊的路线,看能否遇到有标记的线段 preelem3 = 1000000; for (i=array.size()-1;i>=0;i--) { if ( (array[i].elem2!=preelem3)&&(array[i].elem1==tmpK||array[i].elem2==tmpK) ) { if (array[i].path>0)//线段标有1,表示度度熊本身就是第一; 是2表示可以通过加一个线段变为第一 { tag++; } tmpK=array[i].elem1==tmpK?array[i].elem2:array[i].elem1; preelem3 = array[i].elem3; } } if (tag>0) //tag>0表示可以通过加线段改为第一,tag的值表示可添加线段的位置的个数 { cout<<"Yes"<<endl; }else{ cout<<"No"<<endl; } } system("pause"); return 0; }