Codeforces Round #288 (Div. 2)【贪心、单调队列、欧拉通路、STL栈】

题目链接


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;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值