pku acm 1009
2011-08-23 13:16
337 查看
-)常规解法,Time Limit Exceeded 设一个点x与周围8个点相减后绝对值的最大值为edv值。 思想: 1)同一行中的相邻点x1,x2,如果x1已经求得它周围的8个点那么对于x2而言只需要计算另外3个点就可以了。 边界情况就是:对于左边界的点必须求周围8个点 2)当两个相邻点x1,x2的edv值都是0时,检查是否存在接下来很多点值都相等的情况,这那么可以加速。 尽管使用了以上两种技术但是速度仍然不够快,平台通不过。 #include <iostream> #include <cstdio> #include <string> #include <cmath> using namespace std; #define L_N(x) (x - 1) #define R_N(x) (x + 1) #define U_N(x,width) (x - width) #define D_N(x,width) (x + width) #define LU_N(x,width) L_N(U_N(x,width)) #define RU_N(x,width) R_N(U_N(x,width)) #define LD_N(x,width) L_N(D_N(x,width)) #define RD_N(x,width) R_N(D_N(x,width)) #define L_BORDER(x,width) (((x-1)%width==0)?1:0) #define R_BORDER(x,width) (((x)%width==0)?1:0) #define U_BORDER(x,width) (((x) >= 1 && (x) <= width)?1:0) #define D_BORDER(x,total,width) (((x) > (total - width) && (x) <= (total))?1:0) int arr[1000][2]; int width; int aa[9]; int totalPixs; int count; int getPix(int x)//x >= 1 { int i; for(i = 0; i < count; i++) { if(x <= arr[i][1]) return arr[i][0]; } return -1; } int getIndex(int x)//x >= 1 { int i; for(i = 0; i < count; i++) { if(x <= arr[i][1]) return i; } return -1; } void get8NPix(int i) { int curPix,tPix; curPix = getPix(i); int j; for(j = 0; j < 9; j++) aa[j] = curPix; aa[4] = curPix; if(!L_BORDER(i,width)) aa[3] = getPix(L_N(i)); if(!R_BORDER(i,width)) aa[5] = getPix(R_N(i)); if(!U_BORDER(i,width)) aa[1] = getPix(U_N(i,width)); if(!D_BORDER(i,totalPixs,width)) aa[7] = getPix(D_N(i,width)); if(!(L_BORDER(i,width) || U_BORDER(i,width))) aa[0] = getPix(LU_N(i,width)); if(!(R_BORDER(i,width) || U_BORDER(i,width))) aa[2] = getPix(RU_N(i,width)); if(!(L_BORDER(i,width) || D_BORDER(i,totalPixs,width))) aa[6] = getPix(LD_N(i,width)); if(!(R_BORDER(i,width) || D_BORDER(i,totalPixs,width))) aa[8] = getPix(RD_N(i,width)); } void get3NPix(int i) { aa[0] = aa[1]; aa[1] = aa[2]; aa[3] = aa[4]; aa[4] = aa[5]; aa[6] = aa[7]; aa[7] = aa[8]; aa[2] = aa[5] = aa[8] = -1; if(!(R_BORDER(i,width) || U_BORDER(i,width))) aa[2] = getPix(RU_N(i,width)); if(!R_BORDER(i,width)) aa[5] = getPix(R_N(i)); if(!(R_BORDER(i,width) || D_BORDER(i,totalPixs,width))) aa[8] = getPix(RD_N(i,width)); } int getMaxDiff(int *aa) { int max = 0; int i,diff; for(i = 0; i < 4; i++) { if(aa[i] == -1)continue; diff = abs(aa[4] - aa[i]); if(diff > max) max = diff; } for(i = 5; i < 9; i++) { if(aa[i] == -1)continue; diff = abs(aa[4] - aa[i]); if(diff > max) max = diff; } return max; } int main() { int px, rle; int begin,end,h; int i; //freopen("in.txt","r",stdin); cin>>width; while(width) { cout<<width<<endl; totalPixs = count = 0; while(cin>>px>>rle) { if(px == 0 && rle == 0) break; totalPixs += rle;// arr[count][0] = px; arr[count][1] = totalPixs; // ++count; } int max,pmax,pcount; get8NPix(1); pmax = getMaxDiff(aa); pcount = 1; for(i = 2; i <= totalPixs; i++) { if(L_BORDER(i,width)) get8NPix(i); else get3NPix(i); max = getMaxDiff(aa); if(max == 0 && pmax == 0) { h = getIndex(i); if(h == 0) begin = 0; else if(h <= count - 1) begin = arr[h-1][1]; if(i - begin > width) { end = arr[h][1] - width - 1; if(end > i) { pcount += end - i; i = end; } } } if(max == pmax) ++pcount; else { cout<<pmax<<" "<<pcount<<endl; pmax = max; pcount = 1; } } cout<<pmax<<" "<<pcount<<endl; cout<<"0 0"<<endl; cin>>width; } cout<<"0"<<endl; return 1; }
二)下面这种方法来自一位网友,认为只有在输入值发生变化的地方才可能发生edv值的变化。(AC)
如上图中蓝色的方框正是发生输入值变化的点,那么只有这些点及其周围的8个点才可能发生edv值变化。其它点的值都不会变化。
为什么?
现假设从A到B没有发生值变化,且B周围的8个点也没有发生值变化,则很显然d1 = c1 = b1 = a1,d2 = c2 = b2 = a2, d3 = c3 = b3 = a3,因此A的edv值必与B的edv值相等。
因此如果如果从A到B发生edv值变化,那么必然是周围存在输入值变化的点。
对于这题而言,我们只需要计算输入值发生变化处的点及其周围的8个点即可。
#include <iostream> #include <cstdio> #include <string> #include <cmath> #include <map> using namespace std; int arr[1002][2]; int width; int totalPixs; int count; bool insideImage(int dx,int dy)//dx >= 1, dy >= 1 { if(dx >= 1 && dy >= 1 && dx <= width && ((dy-1)*width+dx) <= totalPixs ) return true; return false; } int getPix(int dx,int dy)//dx >= 1, dy >= 1 { int x = (dy-1)*width+dx; for(int i = 1; i < count; i++) { if(x <= arr[i][1]) return arr[i][0]; } return -1; } int getEdv(int dx,int dy) { int cpix = getPix(dx,dy); int max = -1,t; for(int i = dx-1; i <= dx+1; i++) for(int j = dy-1; j <= dy+1; j++) { if(insideImage(i,j)) { t = abs(cpix-getPix(i,j)); if(t > max)max = t; } } return max; } int main() { freopen("in.txt","r",stdin); int px,rle; map<int,int> im; map<int,int>::iterator it; map<int,int>::iterator tor; cin>>width; while(width) { cout<<width<<endl; //initiation arr[0][1] = 0; totalPixs = 0; count = 1; im.clear(); while(cin>>px>>rle) { if(px == 0 && rle == 0) break; totalPixs += rle;// arr[count][0] = px; arr[count][1] = totalPixs; // //cout<<"arr["<<count<<"][0] = "<<arr[count][0] // <<" arr["<<count<<"][1] = "<<arr[count][1]<<endl; ++count; } {//begin_data_analize for(int i = 0; i < count; i++) { int n = arr[i][1] + 1;//输入值发生变化的点 //求n对应的坐标表示,左上角为(1,1),x增长方向为右,y增长方向为下 int x,y,dx,dy; if(n % width == 0) x = width, y = n/width; else x = n%width, y = n/width + 1; //求其点x,y及其周围的8个点的edv值 for(dx = x-1; dx <= x+1; dx++) for(dy = y-1; dy <= y+1; dy++) { if(insideImage(dx,dy)) im.insert(make_pair(((dy-1)*width+dx), getEdv(dx,dy))); } } it = im.begin(); while(it != im.end())//进行编码输出 { tor = it; tor++; for(;tor != im.end() && tor->second == it->second;tor++); if(tor == im.end())break; cout<<it->second<<" "<<(tor->first - it->first)<<endl; it = tor; } cout<<it->second<<" "<<(totalPixs - it->first + 1)<<endl; //cout<<endl; }//end_data_analize cout<<"0 0"<<endl; cin>>width; } cout<<"0"<<endl; return 1; }
相关文章推荐
- HDU 5876 Sparse Graph2016 ACM/ICPC Asia Regional Dalian Online 1009
- PKU ACM/ICPC竞赛队最近八年比赛成绩
- 南邮acm 1009 2的N次方 java解法
- http://acm.pku.edu.cn/JudgeOnline/problem?id=1284 (原根)
- 假金币问题-PKUacm1029-ACM
- PKU ACM 1080 源代码
- 杭电 ACM 1009 FatMouse' Trade
- 杭电ACM 1008 1009
- ACM PKU 题目分类(完整整理版本)
- pku acm 2488 源码
- PKU ACM 1012 Joseph 约瑟夫
- 武汉科技大学ACM :1009: 华科版C语言程序设计教程(第二版)习题6.11
- Problems by Topic @ acm.pku.edu.cn
- Pku acm 1458 Common Subsequence 动态规划题目解题报告(五)
- Pku acm 1274 The Perfect Stall 数据结构题目解题报告(十三)---- 匈牙利算法求二分图的最大匹配
- Pku acm 1961 Period数据结构题目解题报告(十九)----kmp算法
- ACM--猫鼠交易--贪心--HDOJ 1009--FatMouse' Trade
- 2017 ACM/ICPC Asia Regional Qingdao Online 1009(最大流Dinic算法)
- PKUACM_HUMAN GENE FUNCTION
- pku 1009