题目:http://www.nocow.cn/index.php/Translate:USACO/window
题目大意是在四个窗体操作和一个显示操作过程中,显示指定窗体的可见窗体比率。
我的第一种方法是使用模拟的方法,声明了一个长度为62的窗体结构体数组,0-9表示窗体标示为‘0’-‘9’的窗口,10-36标示‘a’-‘z’的窗体。然后不断的读取指令,对窗体的操作改为对结构体数组中窗体的修改。
窗体结构体如下:
//窗体结构体 struct Window { int x1, y1; int x2, y2; int layer; };
然后针对输出窗体的比率,使用微元法,即一列一列的进行切割。
具体代码如下:
#include <iostream> #include <fstream> #include <iomanip> #include <string> #define TYPE 62 #define max(a,b) (a)>(b)?(a):(b) #define min(a,b) (a)<(b)?(a):(b) using namespace std; //窗体结构体 struct Window { int x1, y1; int x2, y2; int layer; }; bool use[TYPE]; Window windows[TYPE]; int number = 0; ifstream fin("window.in"); ofstream fout("window.out"); int getindex(char c) { int index = 0; if (c>='0' && c<='9') { index = c - '0'; } else if (c >= 'a' && c<= 'z') { index = c-'a' + 10; } else if (c>='A' && c<= 'Z') { index = c - 'A' + 36; } return index; } int getpix(string line, int * start) { (*start) ++; int pix = 0; while (line[(*start)] != ',' && line[(*start)] != ')') { pix = pix * 10 + line[*start] - '0'; (*start) ++; } return pix; } //创建窗体操作 void woperate(string cmd) { char c=cmd[2]; int start = 3; int x1= getpix(cmd, &start); int y1 = getpix(cmd, &start); int x2 = getpix(cmd, &start); int y2 = getpix(cmd, &start); int index = getindex(c); use[index] = true; number ++; windows[index].x1 = min(x1,x2); windows[index].y1 = min(y1,y2); windows[index].x2 = max(x1,x2); windows[index].y2 = max(y1,y2); windows[index].layer = number; } //置顶操作 void toperate(string cmd) { char c=cmd[2]; int index = getindex(c); for (int i=0; i < TYPE; i ++) { if (use[i]) { if (windows[i].layer > windows[index].layer) { windows[i].layer --; } }//end if }//end for windows[index].layer = number; } //置底操作 void boperate(string cmd) { char c=cmd[2]; int index = getindex(c); for (int i=0; i < TYPE; i ++) { if (use[i]) { if (windows[i].layer < windows[index].layer) { windows[i].layer ++; } }//end if }//end for windows[index].layer = 1; } //删除操作 void doperate(string cmd) { char c=cmd[2]; int index = getindex(c); use[index] = false; for (int i=0; i < TYPE; i ++) { if (use[i]) { if (windows[i].layer > windows[index].layer) { windows[i].layer --; } }//end if }//end for number --; } //获取每列的可见面积 int getViewColumn(int x, int y1, int y2, int layer,int step) { if (y1>= y2) { return 0; } if (step == TYPE) { return y2-y1; } else { if (use[step]) { if (windows[step].layer > layer) { if (windows[step].x1<= x && windows[step].x2 > x) { if (y2 <= windows[step].y1) { return getViewColumn(x, y1,y2,layer,step+1); } else if (y1 < windows[step].y1 && y2 <= windows[step].y2) { return getViewColumn(x, y1, windows[step].y1, layer, step+1); } else if (y1 < windows[step].y1 && y2 > windows[step].y2) { int up = getViewColumn(x, y1, windows[step].y1, layer, step+1); int down = getViewColumn(x, windows[step].y2, y2, layer, step+1); return up + down; } else if (y1 >= windows[step].y1 && y2 <= windows[step].y2) { return 0; } else if (y1 >= windows[step].y1 && y1 < windows[step].y2 && y2 > windows[step].y2) { return getViewColumn(x, windows[step].y2, y2, layer, step+1); } else if (y1 >= windows[step].y2) { return getViewColumn(x, y1, y2, layer, step+1); } } else return getViewColumn(x, y1,y2,layer,step+1); }//窗体在上面的 else { return getViewColumn(x, y1,y2,layer,step+1); }//窗体在下面的 } else { return getViewColumn(x, y1,y2,layer,step+1); }//没有这个窗体 } //end else } //计算面积操作 void soperate(string cmd) { char c=cmd[2]; int index = getindex(c); //计算面积 int area = (windows[index].x2 - windows[index].x1) * (windows[index].y2 - windows[index].y1); //可见面积 int view = 0; for(int i=windows[index].x1; i < windows[index].x2; i ++) { view += getViewColumn(i, windows[index].y1, windows[index].y2, windows[index].layer, 0); } double ratio = (double)100 *((double)view /(double)area); fout << ratio << endl; } //读取指令 void read() { string cmd; while (getline(fin, cmd)) { if (cmd[0] == 'w') { woperate(cmd); } else if (cmd[0] == 't') { toperate(cmd); } else if (cmd[0] == 'b') { boperate(cmd); } else if (cmd[0] == 'd') { doperate(cmd); } else if (cmd[0] == 's') { soperate(cmd); } }//end while } int main() { fout <<fixed<<setprecision(3); read(); return 0; }
运行在TEST10的时候超时了,晚上再想办法改进一下吧。
Executing... Test 1: TEST OK [0.000 secs, 3016 KB] Test 2: TEST OK [0.000 secs, 3016 KB] Test 3: TEST OK [0.000 secs, 3016 KB] Test 4: TEST OK [0.011 secs, 3016 KB] Test 5: TEST OK [0.011 secs, 3016 KB] Test 6: TEST OK [0.022 secs, 3016 KB] Test 7: TEST OK [0.043 secs, 3016 KB] Test 8: TEST OK [0.086 secs, 3016 KB] Test 9: TEST OK [0.389 secs, 3016 KB] > Run 10: Execution error: Your program (`window') used more than the allotted runtime of 1 seconds (it ended or was stopped at 1.566 seconds) when presented with test case 10. It used 3016 KB of memory.
