题目链接
A. Pasha and Pixels
一个贪心判断它是在四周的那一个方块内满足条件即可。直接贪心。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define _ABS(x, y) ( x > y ? (x - y) : (y - x) )
#define lowbit(x) ( x&( -x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
int N, M, K;
bool vis[1007][1007] = {false};
inline bool check(int x, int y)
{
if(vis[x-1][y] && vis[x-1][y-1] && vis[x][y-1]) return true;
if(vis[x+1][y] && vis[x+1][y-1] && vis[x][y-1]) return true;
if(vis[x-1][y] && vis[x-1][y+1] && vis[x][y+1]) return true;
if(vis[x+1][y] && vis[x+1][y+1] && vis[x][y+1]) return true;
return false;
}
int main()
{
scanf("%d%d%d", &N, &M, &K);
int ans = 0;
for(int i=1, x, y; i<=K; i++)
{
scanf("%d%d", &x, &y);
if(vis[x][y]) continue;
vis[x][y] = true;
if(!ans && check(x, y)) ans = i;
}
printf("%d\n", ans);
return 0;
}
B. Anton and currency you all know
贪心,依然是贪心,要么直接找到一个最前面的刚好比它小的偶数,直接交换,不然的话,就是换最后一个偶数了。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define _ABS(x, y) ( x > y ? (x - y) : (y - x) )
#define lowbit(x) ( x&( -x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 1e5 + 7;
int N, a[maxN];
char s[maxN];
int main()
{
scanf("%s", s);
N = (int)strlen(s);
bool ou_num = false;
for(int i=0; i<N; i++)
{
a[i] = s[i] - '0';
if((a[i] & 1) == 0) ou_num = true;
}
if(!ou_num) { printf("-1\n"); return 0; }
int las_val = a[N - 1], las_id = 0;
bool ok = false;
for(int i=0; i<N; i++)
{
if((a[i] & 1) == 0)
{
if(a[i] < las_val)
{
swap(a[i], a[N - 1]);
ok = true;
break;
}
las_id = i;
}
}
if(!ok) swap(a[las_id], a[N - 1]);
for(int i=0; i<N; i++) printf("%d", a[i]);
printf("\n");
return 0;
}
C. Anya and Ghosts
这道题其实我一看觉得就是一个从后往前的单调队列罢了。贪心——标签如是打到。
直接从后往前,能放多前面就放多前面,然后直接记录答案,此法一定是最贪心的。
首先,仍然是先要判断是否有可行解,没有直接-1了。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define _ABS(x, y) ( x > y ? (x - y) : (y - x) )
#define lowbit(x) ( x&( -x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 305;
int N, T, R, w[maxN], ans = 0;
int que[maxN << 2], top, fail;
int main()
{
scanf("%d%d%d", &N, &T, &R);
for(int i=1; i<=N; i++) scanf("%d", &w[i]);
if(T + 1 < R + 1) { printf("-1\n"); return 0; }
top = 0; fail = 0;
for(int i=w[N] - T + R - 1; i>=w[N] - T; i--)
{
que[fail++] = i;
ans ++;
}
for(int i = N - 1, need, now_have; i >= 1; i--)
{
while(top < fail && que[top] >= w[i])
{
top++;
}
now_have = fail - top;
need = R - now_have;
for(int j=w[i] - T + need - 1; j>=w[i] - T; j--)
{
que[fail++] = j;
ans ++;
}
}
printf("%d\n", ans);
return 0;
}
D. Tanya and Password
欧拉通路好题!!!
一开始的时候,我想了一下,不知道该怎么解决一个“中断”的问题(可能微机学多了,用了这个名词解释哈哈哈)。
如图类型:
所以,我们可以拿栈维护一下,重点就是栈,其他XJB操作都是不得正解的!!!
譬如,我们访问到了,我们访问下一个结点,然后把后继所有访问完了,也就是把后继所有的都是进栈了。于是,是不是满足了我们所要的输出欧拉通路的作用了!!!太巧了,好!
当然,不要忘记特判,假如大家都是"aaa"的时候,实际上我们要给起点定义的哟~
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define _ABS(x, y) ( x > y ? (x - y) : (y - x) )
#define lowbit(x) ( x&( -x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 4e5 + 7;
int N, In_du[maxN] = {0}, Out_du[maxN] = {0}, tot = 0, root[maxN];
inline int fid(int x) { return x == root[x] ? x : root[x] = fid(root[x]); }
char s[maxN][4], ch[maxN][2];
string tmp;
unordered_map<string, int> Hash_mp;
inline int Hash_id(char fir, char sec)
{
tmp.clear(); tmp += fir; tmp += sec;
if(Hash_mp[tmp]) return Hash_mp[tmp];
else
{
ch[++tot][0] = fir; ch[tot][1] = sec;
return Hash_mp[tmp] = tot;
}
}
int head[maxN], cnt;
struct Eddge
{
int nex, to;
Eddge(int a=-1, int b=0):nex(a), to(b) {}
}edge[maxN << 1];
inline void addEddge(int u, int v) { edge[cnt] = Eddge(head[u], v); head[u] = cnt++; }
stack<char> ans;
stack<int> S;
void dfs(int st)
{
S.push(st);
int u, v;
while(!S.empty())
{
u = S.top();
if(~head[u])
{
v = edge[head[u]].to;
head[u] = edge[head[u]].nex;
S.push(v);
}
else
{
ans.push(ch[u][1]);
S.pop();
}
}
}
inline void init()
{
tot = 0;
for(int i=0; i<=(N << 1); i++)
{
head[i] = -1;
root[i] = i;
}
}
int main()
{
scanf("%d", &N);
init();
for(int i=1, u, v, fu, fv; i<=N; i++)
{
scanf("%s", s[i]);
u = Hash_id(s[i][0], s[i][1]); v = Hash_id(s[i][1], s[i][2]);
Out_du[u]++; In_du[v]++;
addEddge(u, v);
fu = fid(u); fv = fid(v);
if(fu ^ fv) root[fu] = fv;
}
int KK = 0;
for(int i=1; i<=tot; i++) KK += (i == fid(i));
if(KK ^ 1) { printf("NO\n"); return 0; }
bool flag = true;
int st = 0, nono = 0;
for(int i=1; i<=tot; i++)
{
if(In_du[i] == Out_du[i]) continue;
if(Out_du[i] - In_du[i] == 1)
{
if(st)
{
flag = false;
break;
}
else st = i;
}
else if(Out_du[i] - In_du[i] == -1)
{
if(++nono > 1) { flag = false; break; }
}
else { flag = false; break; }
}
if(!flag) { printf("NO\n"); return 0; }
if(!st) st = 1; //全相同情况
dfs(st);
ans.push(ch[st][0]);
printf("YES\n");
while(!ans.empty())
{
printf("%c", ans.top());
ans.pop();
}
printf("\n");
return 0;
}
E. Arthur and Brackets
一道括号匹配问题。这道题可以直接dfs去跑,当然时间上慢得多了。这里有一个贪心的策略。
我们似乎应当去尽可能的先满足后面的条件,就譬如说,我们发现,如果栈顶对应的那个“L~R”,它所对应的位置加上至少的L长度,还是不足以抵达目前的位置的话,我们当然是还不能放它进去了,如果说它+R又小于了目前为止,当然这是违法的。其次,如果现在它就在这个范围内,我们是可以放入的。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define _ABS(x, y) ( x > y ? (x - y) : (y - x) )
#define lowbit(x) ( x&( -x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 605;
int N, l[maxN], r[maxN], cnt, pos[maxN];
char ans[maxN << 1];
stack<int> st;
int main()
{
scanf("%d", &N);
for(int i=1; i<=N; i++) scanf("%d%d", &l[i], &r[i]);
bool flag = true;
for(int i=1, u; i<=N; i++)
{
st.push(i);
ans[cnt++] = '(';
pos[i] = cnt - 1;
while(!st.empty())
{
u = st.top();
if(pos[u] + l[u] > cnt)
{
break;
}
if(pos[u] + r[u] < cnt)
{
flag = false;
break;
}
ans[cnt++] = ')';
st.pop();
}
}
if(!flag || cnt < 2 * N) printf("IMPOSSIBLE\n");
else printf("%s\n", ans);
return 0;
}