TC训练

SRM 400 DIV 2

1000pt

枚举第一行和第一列,复杂度为O(2^16)

然后贪心和开关问题类似。

#line 2 "LightedPanels.cpp"
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <ctime>
using namespace std;
typedef long long ll;

class LightedPanels {
public:
    int g[11][11],gg[11][11];
    int H , W;
    void flip(int x,int y) {
        for(int i = -1; i <= 1; ++i)
            for(int j = -1; j <= 1; ++j) {
                int xx = x + i;
                int yy = y + j;
                if(xx < 0 || xx >= H || yy < 0 || yy >= W) continue;
                gg[xx][yy] = !gg[xx][yy];
            }
    }
    int solve() {
        int ans = 0;
        for(int i = 1; i < H; ++i)
            for(int j = 1; j < W; ++j)
                if(gg[i-1][j-1] == 0) {
                    ++ans;
                    flip(i,j);
                }
        for(int i = 0; i < H; ++i)
            for(int j = 0; j < W; ++j)
                if(gg[i][j] != 1) return 65;
        return ans;
    }
    int minTouch(vector <string> board) {
        H = board.size();
        W = board[0].size();
        memset(g,0,sizeof(g));
        memset(gg,0,sizeof(gg));
        for(int i = 0; i < H; ++i) {
            string str = board[i];
            for(int j = 0; j < str.size(); ++j)
                if(str[j] == '*') g[i][j] = 1;
                else g[i][j] = 0;
        }
        int all = 1<<16,MIN = 65;
        for(int s = 0; s < all; ++s) {
            int k = 1,step = 0;
            for(int x = 0; x < 9; ++x)
                for(int y = 0; y < 9; ++y)
                    gg[x][y] = g[x][y];
            for(int i = 0; i < W; ++i) {
                if(s&k) flip(0,i),++step;
                k <<= 1;
            }
            for(int i = 1; i < H; ++i) {
                if(s&k) flip(i,0),++step;
                k <<= 1;
            }
            MIN = min(MIN,step+solve());
        }
        if(MIN >= 65) MIN = -1;
        return MIN;
    }
// END CUT HERE

};


SRM 589 DIV 2

500pt卡了好久,想用dp做的,边界处理想了半天。最后看了题解,用贪心过了

1000pt留坑

SRM 590 DIV 2

1000pt留坑

SRM 591 DIV 2

500pt好题

1000pt留坑

SRM 592 DIV 2

1000pt留坑

SRM 593 DIV 2

1000pt留坑

SRM 594 DIV 2

1000pt留坑

SRM 595 DIV 2

1000pt留坑

SRM 596 DIV 2

1000pt留坑

SRM 597 DIV 2

SRM 598 DIV 2

SRM 599 DIV 2

SRM 600 DIV 2

1000pt留坑

SRM 601 DIV 2

1000pt留坑

SRM 602 DIV 2:

1000分的题卡了一天。

既然决定要看题解,就要看的认真。

看一段跳一段,再自己想一段,反而没有真正理解题解的内涵。

好题,以后再做一遍。

SRM 603 DIV 2

SRM 604 DIV 2

SRM 605 DIV 2

1000pt留坑

SRM 607 DIV 2

1000pt留坑

SRM 612 DIV 2

SRM 624 DIV 2

SRM 625 DIV 2

SRM 626 DIV 2

SRM 631 DIV 2

500pt

贪心思想:尽可能的把所有点往前放

class CatsOnTheLineDiv2
{
        public:
        map<int,int>can,now,S;
        string getAnswer(vector <int> position, vector <int> count, int time)
        {
            for(int i = - 2000; i <= 2000; ++i) S[i] = 0,can[i] = 0,now[i] = 0;
            int n = position.size();
            for(int i = 0; i< n; ++i) S[position[i]] += count[i],can[position[i]] = 1;
            for(int i = -1000; i <= 1000; ++i)
                if(can[i] == 1){
                    for(int j = -time; j < 0; ++j)
                        if(S[i] > 0 && now[i+j] == 0) --S[i],++now[i+j];
                    if(S[i] != 0 && now[i] != 1) --S[i],now[i] = 1;
                    for(int j = 1; j <= time; ++j)
                        if(S[i] > 0 && now[i+j] == 0)  --S[i],++now[i+j];
            }
            for(int i = -2000; i <= 2000; ++i) if(S[i] > 0) return "Impossible";
            return "Possible";
        }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值