CodeForces#286 div.2 题解
来源:互联网 发布:ajax json遍历 编辑:程序博客网 时间:2024/06/07 07:00
题目链接:http://codeforces.com/contest/505/problems
分类:A、枚举 ;B、BFS;C、DP;D、强联通;E、不明
A题:
题意:在字符串的任意任意位置插入一个字符,使得得到的字符串回文
思路:数据范围很小,字符串长度才10,一共276种情况,枚举就行了。
下面是A题代码:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <vector>#include <deque>#include <list>#include <cctype>#include <algorithm>#include <climits>#include <queue>#include <stack>#include <cmath>#include <map>#include <set>#include <iomanip>#include <cstdlib>#include <ctime>#define ll long long#define ull unsigned long long#define all(x) (x).begin(), (x).end()#define clr(a, v) memset( a , v , sizeof(a) )#define pb push_back#define mp make_pair#define read(f) freopen(f, "r", stdin)#define write(f) freopen(f, "w", stdout)using namespace std;const double pi = acos(-1);inline bool judge ( const string str ){ int a = 0; int b = str.size() - 1; for ( ; a <= b ; ){ if ( str[a] != str[b] ){ return 0; } a ++; b --; } return 1;}int main(){ ios::sync_with_stdio( false ); string a; string b; cin >> a; int cnt = 0; for ( int i = 0; i <= a.size(); i ++ ){ for ( int j = 0; j < 26; j ++ ){ b = a; string k = "a"; k[0] = k[0] + j; b.insert ( i, k ); if ( judge ( b ) ){ cout << b << endl; return 0; } } } cout << "NA" << endl; return 0;}
B题:
题意:给出一张无向图,每条边都有对应的颜色,并且每次只能利用同一种颜色的边。求从a点移动到b点有多少种方案。
思路:同上题,数据范围相当小,只有100个节点,颜色也不超过100种,直接对a点的进行搜索,枚举有多少种颜色的通路能到b点
下面是B题代码:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <vector>#include <deque>#include <list>#include <cctype>#include <algorithm>#include <climits>#include <queue>#include <stack>#include <cmath>#include <map>#include <set>#include <iomanip>#include <cstdlib>#include <ctime>#define ll long long#define ull unsigned long long#define all(x) (x).begin(), (x).end()#define clr(a, v) memset( a , v , sizeof(a) )#define pb push_back#define mp make_pair#define read(f) freopen(f, "r", stdin)#define write(f) freopen(f, "w", stdout)using namespace std;const double pi = acos(-1);const int maxn = 1005;vector<int> g[maxn][maxn];bool SPFA ( int be, int en, int k ){ queue<int> que; que.push ( be ); int vis[1000] = { 0 }; while ( ! que.empty() ){ int tmp = que.front(); que.pop(); for ( int i = 0; i < g[k][tmp].size() && vis[tmp] == 0; i ++ ){ que.push( g[k][tmp][i] ); if ( g[k][tmp][i] == en ) return 1; } vis[tmp] = 1; } return 0;}int main(){ ios::sync_with_stdio( false ); int m, n; while ( cin >> m >> n ){ int a, b, c; for ( int i = 0; i < n; i ++ ){ cin >> a >> b >> c; g[c][a].push_back ( b ); g[c][b].push_back ( a ); } int k; cin >> k; int be, en; for ( int i = 0; i < k; i ++ ){ cin >> be >> en; int cnt = 0; for ( int j = 1; j <= n; j ++ ){ if ( SPFA ( be, en, j ) ) { cnt ++; } } cout << cnt << endl; } } return 0;}
C题:
题意:从起点移动到终点,每次只能比前一次移动距离+1,-1,或者不变。每移动到一个点就将该点的值累加,求最大的情况。
思路:动态规划,有第一维表示位置,第二维表示步长,并且最长步长不能超过250,(1+2+3+.....+250) > 30000 , 所以第二维第长度为500,状态转移方程为 dp[i][j] = dp[i][j] + max ( dp[i-(j-301+n)][j-1], dp[i-(j-301+n)][j], dp[i-(j-301+n)][j+1] ); ans = max ( ans, f[i][j] );
下面是C题代码:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <vector>#include <deque>#include <list>#include <cctype>#include <algorithm>#include <climits>#include <queue>#include <stack>#include <cmath>#include <map>#include <set>#include <iomanip>#include <cstdlib>#include <ctime>#define ll long long#define ull unsigned long long#define all(x) (x).begin(), (x).end()#define clr(a, v) memset( a , v , sizeof(a) )#define pb push_back#define mp make_pair#define read(f) freopen(f, "r", stdin)#define write(f) freopen(f, "w", stdout)using namespace std;const double pi = acos(-1);int num[30005];int dp[30005][605];int main(){ memset ( dp, -1, sizeof ( dp ) ); memset ( num, 0, sizeof ( num ) ); int m, n; int k; cin >> m >> n; for ( int i = 0; i < m; i ++ ){ cin >> k; num[k] ++; } int ans = num[n]; for ( int i = 0; i <= 30000; i ++ ){ for ( int j = 0; j <= 601; j ++ ){ dp[i][j] = -9999999; } } dp[n][301] = num[n]; for ( int i = n + 1; i <= 30000; i ++ ){ for ( int j = 1; j <= 600; j ++ ){ if ( i - ( j - 301 + n ) < 0 || i - ( j - 301 + n ) >= i )continue; dp[i][j] = max ( dp[i][j], dp[i-(j-301+n)][j-1] ); dp[i][j] = max ( dp[i][j], dp[i-(j-301+n)][j] ); dp[i][j] = max ( dp[i][j], dp[i-(j-301+n)][j+1] ); dp[i][j] += num[i]; ans = max ( ans, dp[i][j] ); } } cout << ans << endl;}
D题:
题意:给出n个节点与m条有向边,判断最少需要边保证连通性不变
思路:最先想到的判断强联通,一个连通块中有若存在强联通分量,则需要的边数=节点数,若不存在强联通,则需要的边数=节点数-1;然后分别对每个连通块进行查询
PS:本来判强联通想通过tarjan染色,搞了好久搞不出来,看别人代码的时候看到了一种很神奇的代码,就拿来学习了下,果然大有收获。
下面是D题代码:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <vector>#include <deque>#include <list>#include <cctype>#include <algorithm>#include <climits>#include <queue>#include <stack>#include <cmath>#include <map>#include <set>#include <iomanip>#include <cstdlib>#include <ctime>#define ll long long#define ull unsigned long long#define all(x) (x).begin(), (x).end()#define clr(a, v) memset( a , v , sizeof(a) )#define pb push_back#define mp make_pair#define read(f) freopen(f, "r", stdin)#define write(f) freopen(f, "w", stdout)using namespace std;const double pi = acos(-1);#define MAX_V 100005int V, E;int dfn[MAX_V], low[MAX_V];bool instack[MAX_V];int un[MAX_V];int din;int cnt;int colorCnt = 0;stack<int>s;vector<int>Edge[MAX_V];vector<int>g[MAX_V];vector<int>ans;int vis[MAX_V];void init( int m ){ for ( int i = 0; i < MAX_V; i ++ ){ Edge[i].clear(); } for ( int i = 0; i <= MAX_V; i ++ ){ un[i] = i; } ans.clear(); while ( ! s.empty() )s.pop(); clr ( dfn, 0 ); clr ( low, 0 ); clr ( vis, 0 ); clr ( instack, 0 );}int find ( int x ){ if ( x == un[x] ){ return x; } else{ return un[x] = find( un[x] ); }}void merge ( int x, int y ){ x = find( x ); y = find( y ); if ( x == y )return; un[x] = y; return;}int bfs ( int i ){ if ( Edge[i].size() >= 2 ){ int cnt = 0; queue<int> q; for ( int j = 0; j < Edge[i].size(); j ++ ){ if ( vis[Edge[i][j]] == 0 ) q.push( Edge[i][j] ); } while ( ! q.empty() ){ int x = q.front(); q.pop(); cnt ++; for ( int j = 0; j < g[x].size(); j ++ ){ vis[g[x][j]] --; if ( vis[g[x][j]] == 0 ) q.push( g[x][j] ); } } if ( cnt == Edge[i].size() ){ return Edge[i].size() - 1; } else{ return Edge[i].size(); } } return 0;}int main(){ ios::sync_with_stdio( false ); int m, n; while ( cin >> m >> n ){ init ( m ); int a, b; for ( int i = 0; i < n; i ++ ){ cin >> a >> b; a --; b --; merge ( a, b ); g[a].push_back( b ); vis[b] ++; } for ( int i = 0; i < m; i ++ ){ Edge[find(i)].push_back( i ); } int ans = 0; for ( int i = 0; i < m; i ++ ){ ans += bfs ( i ); } cout << ans << endl; }}
E题没做。
(未完待续)
- CodeForces#286 div.2 题解
- 【codeforces #286(div 2)】ABCD题解
- 【Codeforces】【#FF Div.2】【题解】
- Codeforces #206 Div 2 题解
- codeforces 459 (div 2) 题解
- CodeForces#285 div.2 题解
- CodeForces#287 div.2 题解
- CodeForces#290 div.2 题解
- CodeForces #291 div.2 题解
- CodeForces #292 div.2 题解
- CodeForces #293 div.2 题解
- CodeForces #294 div.2 题解
- Codeforces #446 (Div. 2) 题解
- Codeforces#449 div 2 题解
- 【codeforces】Codeforces Round #276 (Div. 2) 题解
- 【codeforces】Codeforces Round #277 (Div. 2) 题解
- 【codeforces】Codeforces Round #279 (Div. 2) 题解
- 【codeforces】Codeforces Round #283 (Div. 2) 【题解】
- 安装django-cms时遇到的PNG support to Pillow 问题解决方法
- JAVA代理模式
- kettle —— 数据过滤和值映射
- elasticsearch 索引恢复 查看 API
- 单片机IO相关
- CodeForces#286 div.2 题解
- 华为机试—约瑟夫环替换计数器m(循环链表解决)
- hdu 1402 A * B Problem Plus (FFT + 大数相乘)
- 企业级数据结构-栈的链式存储设计与实现
- 语音编解码
- elasticsearch之sorting and relevance
- Oracle性能分析:开启SQL跟踪和获取trace文件|trace文件解读
- Windows 结构化异常与 C / C++异常的一些事
- Ubuntu的最新信息