http://acm.hdu.edu.cn/showproblem.php?pid=3687/* 题意就是:给你一个n*m的方格,然后有n*n的士兵,现在士兵正在休息,然后要集合的时候,需要组成n*n的方正 现在给你n*n士兵的休息的位置,要求你求出要集合的时候总的需要多少步数(注意只能在水平上移动); 由于只能是水平移动,因此变的很简单了,我一开始以为都要移动最左边去(误解了题意) 首先要开对于x排序 枚举一开始的列数(枚举法) */ #include<iostream> #include<algorithm> using namespace std; struct Point { int x; int y; friend bool operator<(const Point &p1, const Point &p2)//首先是按照x坐标从小到大排列 { if(p1.x == p2.x) return p1.y < p2.y; else p1.x < p2.x; } }; Point p[3600]; inline int min(int a, int b) { if(a < b) return a; else return b; } inline int abs(int a) { if(a < 0) a = -a; return a; } int main() { // freopen("in.txt", "r", stdin); int i, j, k, m, n, t, ans, temp; while(scanf("%d %d", &n, &m)) { if(n == 0 && m == 0) break; int size = n*n; for(i=0; i<size; i++) { scanf("%d %d", &p[i].x, &p[i].y); } sort(p, p+size); ans = 1<<30; for(i=1; i<=m-n+1; i++)//枚举开始列的位置 { temp = 0; t = 0; for(j=0; j<n; j++) for(k=0; k<n; k++) { temp += abs(i+k-p[t].y);//寻找要移动的步数 t++; } ans = min(temp, ans); } printf("%d/n", ans); } return 0; }