【题目来源】http://www.codeforces.com/contest/263
【A. Beautiful Matrix】
【解析】模拟即可。按照题目的意思,找到1所在的位置(x, y),然后输出abs(x - 3) + abs(y - 3)。
1 #include <iostream> 2 #include <cmath> 3 4 using namespace std; 5 6 int X, Y; 7 8 int main() 9 { 10 for (int i = 1; i <= 5; i ++) 11 for (int j = 1, a; j <= 5; j ++) 12 { 13 cin >> a; 14 if (a) X = i, Y = j; 15 } 16 cout << abs(3 - X) + abs(3 - Y) << endl; 17 return 0; 18 }
【B. Squares】
【解析】贪心。每个正方形都是以(0,0)和(ai,ai)为顶点的,因此将输入的数据按照ai进行排序,输出(A[N - K + 1], 0)即是符合题意的坐标。
1 #include <iostream> 2 #include <algorithm> 3 4 using namespace std; 5 6 int N, K, A[51]; 7 8 int main() 9 { 10 cin >> N >> K; 11 for (int i = 1; i <= N; i ++) cin >> A[i]; 12 sort(A + 1, A + 1 + N); 13 if (N - K < 0) cout << -1 << endl; 14 else cout << A[N - K + 1] << " " << 0 << endl; 15 return 0; 16 }
【C. Circle of Numbers】
【解析】枚举。根据题目的意思可得:对于每个点,有4个点与之相连;对于2个相邻的点,它们的公共点有2个。首先,通过枚举决定前3个数进入队列,接着,取出队列的末尾2个数,由这2个数决定的公共点必然有一个在队列中,另一个不在队列中,把不在队列中的数放进队列。接着重复以上过程,直到所有的数字都能够合法地进入队列,那么就说明找到了这样的环,否则不存在这样的环。另外,读入数据的时候,如果有某个数的度不为4,那么直接就可以判断不存在这样的环。
1 #include <cstdio> 2 #include <cstring> 3 #include <deque> 4 5 //#define FILE_IO 6 7 using namespace std; 8 9 const int Maxn = 100001; 10 11 struct edge 12 { 13 int v; 14 edge* next; 15 edge(int _v, edge* _next) : v(_v), next(_next) {} 16 }* E[Maxn]; 17 18 bool hash[Maxn]; 19 int N, Cnt, Ans[Maxn], Deg[Maxn]; 20 deque <int> Q; 21 22 void Print() 23 { 24 for (int i = 1; i < N; i ++) printf("%d ", Ans[i]); 25 printf("%d\n", Ans[N]); 26 } 27 28 int Find(int x, int y) 29 { 30 for (edge* j = E[x]; j; j = j -> next) 31 for (edge* k = E[y]; k; k = k -> next) 32 if ((hash[j -> v] == false) && (j -> v == k -> v)) return j -> v; 33 return 0; 34 } 35 36 bool Work(int x, int y) 37 { 38 Q.clear(); Cnt = 0; memset(hash, 0, sizeof(hash)); 39 Q.push_back(x), Q.push_back(y); 40 Ans[++ Cnt] = 1; Ans[++ Cnt] = x; Ans[++ Cnt] = y; 41 hash[1] = hash[x] = hash[y] = true; 42 while (Q.size()) 43 { 44 int x = Q.front(); Q.pop_front(); 45 int y = Q.front(); Q.pop_front(); 46 int z = Find(x, y); 47 if (z) 48 { 49 Q.push_back(y); Q.push_back(z); hash[z] = true; 50 Ans[++ Cnt] = z; 51 } 52 else if (Cnt == N) return true; 53 } 54 return false; 55 } 56 57 bool Check(int x, int y) 58 { 59 for (edge* j = E[x]; j; j = j -> next) 60 if (j -> v == y) return true; 61 return false; 62 } 63 64 bool Solve() 65 { 66 int tmp[5], tcnt = 0; 67 for (edge* j = E[1]; j; j = j -> next) tmp[++ tcnt] = j -> v; 68 for (int i = 1; i <= 4; i ++) 69 for (int j = 1; j <= 4; j ++) 70 { 71 if (i == j) continue; 72 int x = tmp[i], y = tmp[j]; 73 if (!Check(x, y)) continue; 74 if (Work(x, y)) return true; 75 } 76 return false; 77 } 78 79 void edgeAdd(int x, int y) 80 { 81 E[x] = new edge(y, E[x]); 82 E[y] = new edge(x, E[y]); 83 } 84 85 bool Init() 86 { 87 scanf("%d", &N); 88 for (int i = 1, x, y; i <= N * 2; i ++) 89 { 90 scanf("%d%d", &x, &y); 91 Deg[x] ++; Deg[y] ++; 92 edgeAdd(x, y); 93 } 94 for (int i = 1; i <= N; i ++) 95 if (Deg[i] != 4) return false; 96 return true; 97 } 98 99 int main() 100 { 101 #ifdef FILE_IO 102 freopen("test.in", "r", stdin); 103 #endif // FILE_IO 104 if ((!Init()) || (!Solve())) printf("-1\n"); 105 else Print(); 106 return 0; 107 }
【D. Cycle in Graph】
【解析】图论。从1个点进行DFS,当遇到未标记的点时候标记为已走。直到DFS到某个点,会发现所有和它相连的点都已经被标记上了。这说明了和它相连的这些点都已经存在于前面DFS的路径中了,由于这个点的度至少为K,也就是说,从已走路径中最早出现的和这个点相连的那个点开始,一直到当前的这个点结束,至少存在一个长度为K+1的圈。
1 #include <cstdio> 2 #include <climits> 3 #include <algorithm> 4 5 //#define FILE_IO 6 7 using namespace std; 8 9 const int Maxn = 1e5 + 1; 10 11 struct edge 12 { 13 int v; 14 edge* next; 15 edge(int _v, edge* _next) : v(_v), next(_next) {} 16 }* E[Maxn]; 17 18 int N, M, K, Cnt, S[Maxn], Visit[Maxn]; 19 20 void Solve() 21 { 22 S[Visit[1] = ++ Cnt] = 1; 23 while (1) 24 { 25 int i = S[Cnt]; bool flag = false; 26 for (edge* j = E[i]; j; j = j -> next) 27 { 28 int v = j -> v; 29 if (!Visit[v]) 30 { 31 S[Visit[v] = ++ Cnt] = v; 32 flag = true; 33 break; 34 } 35 } 36 if (!flag) 37 { 38 int Min = INT_MAX; 39 for (edge* j = E[i]; j; j = j -> next) 40 { 41 int v = j -> v; Min = min(Min, Visit[v]); 42 } 43 printf("%d\n", Cnt - Min + 1); 44 for (int i = Min; i < Cnt; i ++) printf("%d ", S[i]); 45 printf("%d\n", S[Cnt]); 46 return ; 47 } 48 } 49 } 50 51 inline void edgeAdd(int x, int y) 52 { 53 E[x] = new edge(y, E[x]); 54 E[y] = new edge(x, E[y]); 55 } 56 57 void Init() 58 { 59 scanf("%d%d%d", &N, &M, &K); 60 for (int i = 1, x, y; i <= M; i ++) 61 { 62 scanf("%d%d", &x, &y); 63 edgeAdd(x, y); 64 } 65 } 66 67 int main() 68 { 69 #ifdef FILE_IO 70 freopen("test.in", "r", stdin); 71 #endif // FILE_IO 72 Init(); 73 Solve(); 74 return 0; 75 }
【E. Rhombus】
【解析】模拟。最没有想到的是这个题目,难度确实不大。模拟即可。不过同样需要处理一些技巧,具体看代码就OK。
1 #include <cstdio> 2 3 //#define FILE_IO 4 5 using namespace std; 6 7 int N, M, K, Ansx, Ansy; 8 long long Max, A[1001][1001], Sum[1001][1001]; 9 10 void Print() 11 { 12 printf("%d %d\n", Ansx, Ansy); 13 } 14 15 inline long long Count(int x1, int y1, int x2, int y2) 16 { 17 return Sum[x2][y2] + Sum[x1 - 1][y1 - 1] - Sum[x2][y1 - 1] - Sum[x1 - 1][y2]; 18 } 19 20 void Solve() 21 { 22 int im = N - K + 1, jm = M - K + 1; 23 for (int i = K; i <= im; ++i) 24 for (int j = K; j <= jm; ++j) 25 { 26 long long tmp = 0; 27 for (int k = 1; k <= K; ++k) 28 tmp += Count(i - K + k, j - k + 1, i + K - k, j + k - 1); 29 if (tmp >= Max) Max = tmp, Ansx = i, Ansy = j; 30 } 31 } 32 33 void Init() 34 { 35 scanf("%d%d%d", &N, &M, &K); 36 for (int i = 1; i <= N; ++i) 37 for (int j = 1; j <= M; ++j) 38 scanf("%d", &A[i][j]); 39 for (int i = 1; i <= N; ++i) 40 for (int j = 1; j <= M; ++j) 41 A[i][j] += A[i - 1][j]; 42 for (int i = 1; i <= N; ++i) 43 for (int j = 1; j <= M; ++j) 44 Sum[i][j] = Sum[i][j - 1] + A[i][j]; 45 } 46 47 int main() 48 { 49 #ifdef FILE_IO 50 freopen("test.in", "r", stdin); 51 #endif // FILE_IO 52 Init(); 53 Solve(); 54 Print(); 55 return 0; 56 }