比赛链接:
http://codeforces.com/contest/676
A. Nicholas and Permutation
分析:
水题,找到1和n到两边距离的最大值即可。
代码:
/*
--Codeforces 345 div2
--Create by jiangyuzhu
--2016/5/26
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
#define sa(n) scanf("%d", &(n))
#define pl(x) cout << #x << " " << x << endl
#define mdzz cout<<"mdzz"<<endl;
int main (void)
{
int n;cin>>n;
int a;
int p1, p2;
for(int i = 1; i <= n; i++){
cin>>a;
if(a == 1) p1 = i;
if(a == n) p2 = i;
}
int res = max(p1 - 1, n - p1);
int res2 = max(p2 - 1, n - p2);
cout<<max(res, res2)<<endl;
return 0;
}
B.Pyramid of Glasses
分析:
模拟一下倒水的过程。注意用double
代码:
/*
--Codeforces 345 div2
--Create by jiangyuzhu
--2016/5/26
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
#define sa(n) scanf("%d", &(n))
#define sal(n) scanf("%I64d", &(n))
#define pl(x) cout << #x << " " << x << endl
#define mdzz cout<<"mdzz"<<endl;
double a[10 + 5][10 + 5];
int main (void)
{
int n, t;cin>>n>>t;
a[1][1] = t;
int cnt = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= i; j++){
if(a[i][j] >= 1){
a[i + 1][j] += (a[i][j] - 1) / 2.0;
a[i + 1][j + 1] += (a[i][j] - 1) / 2.0;
cnt++;
}
}
}
cout<<cnt<<endl;
return 0;
}
C. Vasya and String
题意:
给定序列,可以任意更换k个字符,求更换后可以得到的最长的连续的相同的字符的长度。
分析:
典型的双指针
代码:
/*
--Codeforces 345 div2
--Create by jiangyuzhu
--2016/5/26
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
#define sa(n) scanf("%d", &(n))
#define sal(n) scanf("%I64d", &(n))
#define pl(x) cout << #x << " " << x << endl
#define pr(x) cout << #x << " " << x << ' '
#define mdzz cout<<"mdzz"<<endl;
map<char, int>cnt;
int main (void)
{
int n, k;cin>>n>>k;
string s;cin>>s;
int maxx = 0;
int len = s.length();
int l = 0, r = 1;
cnt[s[0]]++;
int res = 1;
while(l < r && r < len){
cnt[s[r]]++;
if(cnt[s[r]] > maxx){
maxx = cnt[s[r]];
}
if(r - l - maxx + 1<= k){
res = max(res, r - l + 1);
}
if(r - l - maxx + 1 > k){
cnt[s[l]]--;l++;
}
r++;
}
cout<<res<<endl;
return 0;
}
D. Theseus and labyrinth
题意:
不同字符代表不同门的朝向,每秒钟在每块地方可以选择按钮让所有方块顺时针选择90度或者选择向相邻的方块中走。当且仅当两个门朝向相对时,才能从一个门进入另一个门,给定初始地点和终点,问最短时间。
分析:
一道很有意思的bfs。
我们用一个四位的二进制数来表示字符对应的门的情况,这样处理起来就简单了很多。结点保存坐标,时间和旋转的方向。那么对于某个固定的前进方向,我们只要判断旋转之后是否有门对着这个方向即可。
代码:
/*
--Codeforces 345 div2
--Create by jiangyuzhu
--2016/5/26
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
#define pr(x) cout << #x << ": " << x << " "
#define pl(x) cout << #x << ": " << x << endl;
#define sa(x) scanf("%d",&(x))
#define sal(x) scanf("%I64d",&(x))
#define mdzz cout<<"mdzz"<<endl;
const int maxn = 1e3 + 5, oo = 0x3f3f3f3f;
char s[maxn][maxn];
int a[maxn][maxn];
int n, m;
int x1, y1, x2, y2;
struct NODE{int x; int y; int dist;int dir;};
int vis[maxn][maxn][4];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int ans;
int bfs()
{
queue<NODE>q;
q.push((NODE){x1, y1, 0, 0});
vis[x1][y1][0] = 1;
while(!q.empty()){
NODE t = q.front();q.pop();
int xx = t.x, yy = t.y, dir = t.dir;
if(xx == x2 && yy == y2) return t.dist;
for(int i = 0; i < 4; i++){
int nx = xx + dx[i], ny = yy + dy[i];
if(nx >= n || nx < 0 || ny >= m|| ny < 0||vis[nx][ny][dir]) continue;
int aa = a[xx][yy] >> ((i + 4 - dir) % 4) & 1;
int bb = a[nx][ny] >> ((i + 6 - dir) % 4) & 1;
if(aa == 1 && bb == 1){
vis[nx][ny][dir] = 1;
q.push((NODE){nx, ny, t.dist + 1, dir});
}
}
int ndir = (dir + 1) % 4;
if(!vis[xx][yy][ndir]){
vis[xx][yy][ndir] = 1;
q.push((NODE){xx, yy, t.dist + 1, ndir});
}
}
return -1;
}
int main (void)
{
sa(n);sa(m);
for(int i = 0; i < n; i++){
scanf("%s",s[i]);
for(int j = 0; j < m; j++){
if(s[i][j] == '+') a[i][j] = 15;
if(s[i][j] == '-') a[i][j] = 10;
if(s[i][j] == '|') a[i][j] = 5;
if(s[i][j] == '^') a[i][j] = 1;
if(s[i][j] == '>') a[i][j] = 2;
if(s[i][j] == '<') a[i][j] = 8;
if(s[i][j] == 'v') a[i][j] = 4;
if(s[i][j] == 'L') a[i][j] = 7;
if(s[i][j] == 'R') a[i][j] = 13;
if(s[i][j] == 'U') a[i][j] = 14;
if(s[i][j] == 'D') a[i][j] = 11;
if(s[i][j] == '*') a[i][j] = 0;
}
}
sa(x1);sa(y1);sa(x2);sa(y2);
x1--;x2--;y1--;y2--;
printf("%d\n", bfs());
return 0;
}
E. The Last Fight Between Human and AI
题意:
人和AI轮流向形如
P(x) = anxn + an − 1xn − 1 + ... + a1x + a0
的多项式中填系数,AI和人都会选择最优决策。AI先手。
得到的多项式除以
x−k
可以得到另一个多项式的话,人赢。给定当前局面(可能是中间的局面),问最后谁赢。
分析:
首先明确:
(x−k)|F(x)
等价于
F(k)==0
然后我们分情况讨论:
- k=0 ,只要看 a0 能否等于0即可。如果 a0 未填,并且正好轮到AI,那人肯定会输。
- k!=0 ,如果已经填满,只要判断 F(k) 是否等于0即可。否则需要判断最后是谁在填。当剩下最后一个系数 ai 未填时,无论之前填了什么数字,当我们取 x=k 的时候,原不等式即可转化为 t∗k+ai∗ki ,很明显,必定存在一个 ai 使得该不等式等于0。若是人,选择正确的 ai ,人赢。反之,AI任选其他系数,人输。所以只需看最后一个玩家是人还是AI即可。
代码:
/*
--Codeforces 345 div2 E
--Create by jiangyuzhu
--2016/5/27
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
#define sa(n) scanf("%d", &(n))
#define sal(n) scanf("%I64d", &(n))
#define pl(x) cout << #x << " " << x << endl
#define pr(x) cout << #x << " " << x << ' '
const int maxn = 10 + 5, maxm = 1e5 + 5, oo = 0x3f3f3f3f, mod1 = 1e9 + 7, mod2 = 1e9 - 7;
char s[maxn];
int a[maxm];
int cnt, k, n;
bool solve(int fir)
{
if(k == 0){
if(a[0] == oo) return fir == 2;
else return a[0] == 0;
}
if(cnt == 0){
ll res = 0;
ll res2 = 0;
for(int i = n; i >= 0; i--){
res = (res * k % mod1 + a[i]) % mod1;
res2 = (res2 * k % mod2 + a[i]) % mod2;
}
return res == 0 && res2 == 0;
}else{
if((n + 1) & 1) return false;
else return true;
}
}
int main (void)
{
sa(n);sa(k);
cnt = 0;
for(int i = 0; i < n + 1; i++){
scanf("%s", s);
if(s[0] == '?'){
a[i] = oo;
cnt++;
}
else{
bool flag = true;
int len = strlen(s);
for(int j = 0; j < len; j++){
if(s[j] == '-') {flag = false;continue;}
a[i] = a[i] * 10 + s[j] - '0';
}
if(!flag) a[i] = -a[i];
}
}
int fir;
if((n + 1 - cnt) & 1) fir = 2;//人
else fir = 1;//机器
if(solve(fir)) puts("Yes");
else puts("No");
return 0;
}