A题
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <vector> 7 #include <map> 8 #include <queue> 9 10 using namespace std; 11 12 #define LL long long 13 #define eps 1e-8 14 #define inf 0x3f3f3f3f 15 #define lson l, m, rt << 1 16 #define rson m+1, r, rt << 1 | 1 17 #define mnx 1050 18 19 bool g[mnx][mnx]; 20 int main(){ 21 int n, m, k; 22 scanf( "%d%d%d", &n, &m, &k ); 23 int x, y, ans = 0, ok = 0; 24 for( int i = 1; i <= k; ++i ){ 25 scanf( "%d%d", &x, &y ); 26 g[x][y] = 1; 27 if( !ok && g[x-1][y] && g[x-1][y-1] && g[x][y-1] ) 28 ans = i, ok = 1; 29 if( !ok && g[x-1][y] && g[x-1][y+1] && g[x][y+1] ) 30 ans = i, ok = 1; 31 if( !ok && g[x+1][y] && g[x+1][y-1] && g[x][y-1] ) 32 ans = i, ok = 1; 33 if( !ok && g[x+1][y] && g[x+1][y+1] && g[x][y+1] ) 34 ans = i, ok = 1; 35 } 36 cout << ans << endl; 37 return 0; 38 }
B题
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <vector> 7 #include <map> 8 #include <queue> 9 10 using namespace std; 11 12 #define LL long long 13 #define eps 1e-8 14 #define inf 0x3f3f3f3f 15 #define lson l, m, rt << 1 16 #define rson m+1, r, rt << 1 | 1 17 #define mnx 100050 18 19 char s[mnx]; 20 int main(){ 21 gets( s ); 22 int n = strlen( s ), cur = -1; 23 for( int i = n-2; i >= 0; --i ){ 24 int v = s[i] - '0'; 25 if( v % 2 == 0 ){ 26 cur = i; break; 27 } 28 } 29 for( int i = 0; i < n-1; ++i ){ 30 int v = s[i] - '0'; 31 if( v % 2 ) continue; 32 if( s[n-1] > s[i] ){ 33 swap( s[n-1], s[i] ); break; 34 } 35 } 36 int v = s[n-1] - '0'; 37 if( v % 2 ){ 38 if( cur == -1 ) 39 puts( "-1" ); 40 else { 41 swap( s[cur], s[n-1] ); 42 printf( "%s\n", s ); 43 } 44 } 45 else printf( "%s\n", s ); 46 }
C题,暴力模拟就好了。。有m个鬼,每根蜡烛的燃烧时间为t秒,经过一个鬼的时候至少有r跟蜡烛要燃烧,每点燃一根蜡烛需要1秒的时间。数据比较小,可以开一个tim[]数组记录每秒蜡烛正在燃烧的数量
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <vector> 7 #include <map> 8 #include <queue> 9 10 using namespace std; 11 12 #define LL long long 13 #define eps 1e-8 14 #define inf 0x3f3f3f3f 15 #define lson l, m, rt << 1 16 #define rson m+1, r, rt << 1 | 1 17 #define mnx 1050 18 19 int w[mnx], tim[mnx]; 20 int main(){ 21 int n, t, r, ans = 0;; 22 scanf( "%d%d%d", &n, &t, &r ); 23 for( int i = 0; i < n; ++i ) 24 scanf( "%d", &w[i] ); 25 if( r > t ){ 26 puts( "-1" ); return 0; 27 } 28 for( int i = 0; i < n; ++i ){ 29 int tmp = r - tim[w[i]]; 30 if( tmp > 0 ){ 31 for( int j = w[i] - tmp + 1; j <= w[i]; ++j ){ 32 ans++; 33 for( int k = 0; k < t; ++k ) 34 tim[k+j]++; 35 } 36 } 37 } 38 cout << ans << endl; 39 return 0; 40 }
D题。。有n个字符串,每个字符串的长度为3,叫你找出原串。。把字符串abc拆成 ab -> bc,就可以建立一个有向图,然后转化为求欧拉回路或者欧拉通路。求欧拉回路或者通路首先要判定存不存在,存在的话用避圈法,每条边都走一次。还有一个要优化的地方就是由于存在自环,所以dfs的时候每次 fst[u] = nxt[i]; 没有这个优化会tle
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #include<queue> 8 9 using namespace std; 10 11 #define inf 1e10 12 #define eps 1e-6 13 #define LL long long 14 #define ULL unsigned long long 15 #define MP make_pair 16 #define pb push_back 17 #define mnx 400020 18 #define mxn 200020 19 char s[10], ans[mnx*2]; 20 int fst[mnx], vv[mnx], nxt[mnx], in[mxn], out[mxn], e, all, ce; 21 bool vis[mnx]; 22 void add( int u, int v ){ 23 vv[e] = v, nxt[e] = fst[u], fst[u] = e++; 24 } 25 void dfs( int u ){ 26 for( int i = fst[u]; i != -1; i = fst[u] ){ 27 int v = vv[i]; 28 if( !vis[i] ){ 29 vis[i] = 1; 30 ce++; 31 fst[u] = nxt[i]; 32 dfs( v ); 33 } 34 } 35 ans[all++] = (char)( u%1000 ), ans[all++] = (char)( u/1000 ); 36 } 37 int main(){ 38 memset( fst, -1, sizeof(fst) ); 39 int n; 40 scanf( "%d", &n ); 41 for( int i = 0; i < n; ++i ){ 42 scanf( "%s", s ); 43 int u = s[0] * 1000 + s[1], v = s[1] * 1000 + s[2]; 44 add( u, v ); 45 out[u]++, in[v]++; 46 } 47 int cnt = 0; 48 for( int i = 0; i < mxn; ++i ){ 49 if( ( in[i] + out[i] ) % 2 ) 50 cnt++; 51 } 52 if( cnt == 2 ){ 53 for( int i = 0; i < mxn; ++i ){ 54 if( ( out[i] - in[i] == 1 ) ){ 55 dfs( i ); break; 56 } 57 } 58 if( ce != e ) { puts( "NO" ); return 0; } 59 puts( "YES" ); 60 reverse( ans, ans + all ); 61 int j = 1; 62 for( int i = 1; i < all; i += 2 ) 63 ans[j++] = ans[i]; 64 ans[j] = '\0'; 65 cout << ans << endl; 66 } 67 else if( cnt == 0 ){ 68 int ok = 1; 69 for( int i = 0; i < mxn; ++i ){ 70 if( out[i] - in[i] ) 71 ok = 0; 72 } 73 for( int i = 0; i < mxn; ++i ){ 74 if( out[i] ){ 75 dfs( i ); break; 76 } 77 } 78 if( ce != e || !ok ) puts( "NO" ); 79 else{ 80 puts( "YES" ); 81 reverse( ans, ans + all ); 82 int j = 1; 83 for( int i = 1; i < all; i += 2 ) 84 ans[j++] = ans[i]; 85 ans[j] = '\0'; 86 cout << ans << endl; 87 } 88 } 89 else puts( "NO" ); 90 return 0; 91 }
E题。。给你n个区间(L[i], R[i])表示与第 i 个 ‘(’ 匹配的 ‘)’的距离在(L[i],R[i])之间。问你存在满足条件的括号匹配,存在则输出。
不会,找了题解,有两种做法,一种做法就是贪心,把还没匹配到的‘(’压入栈中,然后遇到可以匹配的就先匹配。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #include<queue> 8 9 using namespace std; 10 11 #define inf 1e10 12 #define eps 1e-6 13 #define LL long long 14 #define ULL unsigned long long 15 #define MP make_pair 16 #define pb push_back 17 #define mnx 1220 18 19 int L[mnx], R[mnx], s[mnx], pos[mnx]; 20 char ans[mnx]; 21 int main(){ 22 int n, ok = 1, all = 0, top = 0; 23 scanf( "%d", &n ); 24 for( int i = 1; i <= n; ++i ){ 25 scanf( "%d%d", &L[i], &R[i] ); 26 if( !ok ) continue ; 27 pos[i] = all; 28 ans[all++] = '('; 29 s[++top] = i; 30 while( top > 0 && pos[s[top]] + L[s[top]] <= all ){ 31 if( pos[s[top]] + R[s[top]] >= all ) 32 ans[all++] = ')'; 33 else{ 34 ok = 0; break; 35 } 36 top--; 37 } 38 } 39 if( top > 0 ) ok = 0; 40 if( ok ) printf( "%s\n", ans ); 41 else puts( "IMPOSSIBLE" ); 42 return 0; 43 }
还有一种做法是dp+记忆化搜索。设dp[l][r] 表示第l个左括号到第r个左括号是否成功匹配,
考虑与第l个左括号 匹配的右括号的位置 在第i个左括号的右边, 然后寻找子状态 (l+1, i), (i+1,r)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #include<queue> 8 9 using namespace std; 10 11 #define inf 1e10 12 #define eps 1e-6 13 #define LL long long 14 #define ULL unsigned long long 15 #define MP make_pair 16 #define pb push_back 17 #define mnx 620 18 19 int dp[mnx][mnx], L[mnx], R[mnx], mat[mnx][mnx]; 20 int dfs( int ls, int rs ){ 21 if( ls > rs ) 22 return 1; 23 if( dp[ls][rs] ) return dp[ls][rs]; 24 for( int i = ls; i <= rs; ++i ){ 25 int dis = ( i - ls ) * 2; 26 if( dis >= L[ls] - 1 && dis <= R[ls] - 1 ){ 27 if( dfs( ls+1, i ) == 1 && dfs( i+1, rs ) == 1 ){ 28 mat[ls][rs] = i; 29 return dp[ls][rs] = 1; 30 } 31 } 32 } 33 return dp[ls][rs] = -1; 34 } 35 void print( int ls, int rs ){ 36 if( ls > rs ) return ; 37 printf( "(" ); 38 print( ls+1, mat[ls][rs] ); 39 printf( ")" ); 40 print( mat[ls][rs]+1, rs ); 41 } 42 int main(){ 43 int n; 44 scanf( "%d", &n ); 45 for( int i = 1; i <= n; ++i ){ 46 scanf( "%d%d", &L[i], &R[i] ); 47 } 48 memset( dp, 0, sizeof(dp) ); 49 dfs( 1, n ); 50 //cout << dp[1][n] << endl; 51 if( dp[1][n] != -1 ) 52 print( 1, n ); 53 else puts( "IMPOSSIBLE" ); 54 return 0; 55 }