AtCoder Beginner Contest 269 (A-F)题解

A - Anyway Takahashi

这里我还是关了ll的 C开了忘了关 害的F多了一发罚时

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
//#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

void solve() {
    int a,b,c,d;cin>>a>>b>>c>>d;
    cout<<(a+b)*(c-d)<<endl;
    cout<<"Takahashi"<<endl;
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}

B - Rectangle Detection

你敢信我这道题写了7分钟 原因竟然是我不会while(cin>>g[i])
我不知道他会不会停 然后我又爬罚时 还去acw开样例
思路就是我们只用维护第一个 和 最后一个的信息即可

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
//#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

void solve() {
    string g[11];int n=0;
    while(cin>>g[n])n++;
    int y1,y2,x1,x2,flag=1;
    for(int i=0;i<n;i++){
        for(int j=0;j<g[i].size();j++){
            if(g[i][j]=='#'&&flag){
                flag=0;
                x1=i,y1=j;
            }
            if(g[i][j]=='#'){
                x2=i,y2=j;
            }
        }
    }
    cout<<x1+1<<' '<<x2+1<<endl;
    cout<<y1+1<<' '<<y2+1<<endl;
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}

C - Submask

枚举即可 但是我用了状态压缩dp的那个来枚举 写的很快!

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

void solve() {
    int n;cin>>n;
    vector<int>v;
    while(n){
        v.push_back(n&-n);
        n-=n&-n;
    }
    int x=v.size();
    vector<int>ans;
    for(int i=0;i<(1<<x);i++){
        int now=0;
        for(int j=0;j<x;j++){
            if(i>>j&1){
                now+=v[j];
            }
        }
        ans.push_back(now);
    }
    sort(all(ans));
    for(auto i:ans)cout<<i<<endl;
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}

D - Do use hexagon grid

把连通都贴你脸上了 就直接乱bfs就行了 有绝对值加个1000就行了 反正只输出连通块数量

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int g[2010][2010],n;
int m=1000;
bool st[2010][2010];
int dx[6]={-1,-1,0,0,1,1},dy[6]={-1,0,-1,1,0,1};
void bfs(int x,int y){
    for(int i=0;i<6;i++){
        int nx=x+dx[i],ny=y+dy[i];
        if(nx<0||nx>2000||ny<0||ny>2000)continue;
        if(st[nx][ny]==0&&g[nx][ny]==1){
            st[nx][ny]=1;
            bfs(nx,ny);
        }
    }
}
void solve() {
    cin>>n;
    for(int i=1;i<=n;i++){
        int a,b;cin>>a>>b;
        g[a+m][b+m]=1;
    }
    int ans=0;
    for(int i=0;i<2010;i++){
        for(int j=0;j<2010;j++){
            if(st[i][j]==0&&g[i][j]==1){
                st[i][j]=1;
                bfs(i,j);
                ans++;
            }
        }
    }
    cout<<ans<<endl;
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}

E - Last Rook

八皇后???
我们知道八皇后要是N个都占满的话 肯定是每行每列都不会出现重复的两个
提问20 N<1e3
哦 那直接对行列二分即可
最开始被交互题吓到了跳去看F了 但看了一下队友几分钟就过了 不然可能心态爆炸
最后也是忘记删调试信息wa了一发

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int n;
bool check(int mid){
    cout<<"? "<<1<<' '<<mid<<' '<<1<<' '<<n<<endl;
    fflush(stdout);
    int x;cin>>x;
    if(x!=mid)return 1;
    else return 0;
}
bool check1(int mid){
    cout<<"? "<<1<<' '<<n<<' '<<1<<' '<<mid<<endl;
    fflush(stdout);
    int x;cin>>x;
    if(x!=mid)return 1;
    else return 0;
}
void solve() {
    cin>>n;
    int l=1,r=n;
    while(l<r) {
        int mid = l + r >> 1;
        if (check(mid))r = mid;
        else l = mid + 1;
    }
    int x=l;
    l=1,r=n;
    while(l<r) {
        int mid = l + r >> 1;
        if (check1(mid))r = mid;
        else l = mid + 1;
    }
    int y=l;
    cout<<"! "<<x<<' '<<y;
}
signed main(){
    //fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}

F - Numbered Checker

我们拿着这道题发现N范围1e9
我们考虑不了转移 只能O(1)计算 可能会想到的不优美的做法就是分别对ABCD的奇偶性进行一个分类讨论
会有八种情况 可做 但是并不好写
那我们考虑题干给出的(i-1)x M + j 好像这个M很可疑
我们考虑去掉M 得到和样例相关的图:

很牛逼吧 那我们考虑算一遍M的总和 再算一遍原来的值 就是左边图上的值
具体代码里有注释

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int n,m;
int calc_cnt(int l,int r,int k) { //计算区间[l,r]中 k(0 even/1 odd)的个数
    if (k == 0) {
        if (l % 2 == 0) return (r - l) / 2 + 1;
         else return (r - l + 1) / 2;
    } else {
        if (l % 2 == 1) return (r - l) / 2 + 1;
        else return (r - l + 1) / 2;
    }
}

int get(int l,int r,int cnt) { //等差数列求和公式
    return 1ll*(l+r)*cnt/2; 
}

int calc_sum(int l,int r,int k) { //计算区间[l,r]中 k(0 even/1 odd)的sum
    if (l == r && l % 2 == (k ^ 1)) return 0;
    int st = l,ed = r;
    if (l % 2 == (k ^ 1)) ++ st;
    if (r % 2 == (k ^ 1)) -- ed;
    return get(st,ed,calc_cnt(l,r,k));
}
void solve() {
    cin >> n >> m;
    int q;
    cin >> q;
    while (q--) {
        int A, B, C, D;
        cin >> A >> B >> C >> D;
        int s1 = 0, s2 = 0;// s1表示我们M的sum s2表示我们原本的sum
        for (int k = 0; k <= 1; ++k) {
            int cur_sum = (calc_sum(A, B, k) % mod - calc_cnt(A, B, k) + mod) % mod;
            cur_sum = 1ll * cur_sum * (calc_cnt(C, D, k) % mod) % mod;
            //M的个数计算就是 M的sum-M的cnt 因为第一行没有
            cur_sum = 1ll * cur_sum * m % mod;
            s1 = (1ll * s1 + cur_sum) % mod;
            cur_sum = (1ll * calc_sum(C, D, k) % mod);
            cur_sum = 1ll * cur_sum * calc_cnt(A, B, k) % mod;
            //原本左图的sum 就直接sum*cnt即可
            s2 = (1ll * s2 + cur_sum) % mod;
        }
        cout << (s1 + s2) % mod << endl;
    }
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-09-18 01:21  ycllz  阅读(245)  评论(0)    收藏  举报