Bayan 2015 Contest Warm Up(C 思维+模拟 D 思维+gcd)

题目链接

C. Kamal-ol-molk's Painting

题意:给你n*m的字符串矩阵,含有'X' 和'.'  现在你要求一个a*b矩形的刷子,每次只能向右走或者向下走,问能否将所有的'X’都刷一遍。

做法:暴力枚举a 和b的长度,然后暴力模拟即可,注意这里的时间复杂度应该是n方到n^3/2之间

代码参考:传送门

#include <bits/stdc++.h>
using namespace std;
const int N = 1000 + 10;
char g[N][N];
int n, m, minX, minY, ans;
int sum[N][N], cnt, tot;
int getSum(int a, int b, int x, int y) {
    return sum[a][b] - sum[a][y + 1] - sum[x + 1][b] + sum[x + 1][y + 1];
}
int ok(int a, int b) {
    int posX =minX,posY=minY;
    while(1) {
        if(posX+a-1>n||posY+b-1>m) return 0;
        if(getSum(posX,posY,posX+a-1,posY+b-1)!=a*b) return 0;
        if(getSum(posX,posY,n,m)==a*b&&getSum(posX,posY,posX+a-1,posY+b-1)==a*b) {
            return (cnt+a*b==tot);//终点,有可能在中间停止
        }
        bool flag1 = (a * b) == getSum(posX+1,posY,posX+a,posY+b-1);//向右走一格
        bool flag2 = (a * b) == getSum(posX,posY+1,posX+a-1,posY+b);//向下走一格
        if(!flag1&&!flag2) return 0;
        if(flag1&&flag2) return 0;
        if(flag1) ++posX,cnt+=b;//向右走一格,cnt总数等于列的个数
        else ++posY,cnt+=a;
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i) {
        scanf("%s", g[i] + 1);
    }
    minX = n + 1, minY = m + 1;
    ans = n * m + 1;
    for(int i=n;i>0;--i){
        for(int j=m;0<j;--j) {
            sum[i][j] = sum[i][j] - sum[i + 1][j + 1] + sum[i + 1][j] + sum[i][j + 1] + (g[i][j] == 'X');
            if(g[i][j] == 'X') {
                minX = min(i, minX), minY = min(j, minY);
                ++tot;
            }
        }
    }
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            if(ans <= i * j) continue;
            cnt = 0;
            if(ok(i, j)) ans = i * j;
        }
    }
    printf("%d\n", ans == n * m + 1 ? -1 : ans);

    return 0;
}

D. CGCDSSQ

题意:给你n长度的数组ai,接下来q次询问,输入x  问有多少个区间的gcd等于x

做法:dp[i][j]代表以i结尾的gcd为j的个数,由于gcd的特殊性质,j的个数不会超过log(a[i])个,所以map保存一下,暴力跑一遍就可以了。。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=(b);++i)
    #define mem(a,x) memset(a,x,sizeof(a))
    #define pb push_back
    #define pi pair<int, int>
    #define mk make_pair
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
    const int N=1e5+10;
    map<int,ll>mp1,mp2,ans;
    int n,a[N],q;
    int main()
    {
        cin>>n;
        rep(i,1,n) scanf("%d",&a[i]);
        for(int i=1;i<=n;++i){
            swap(mp1,mp2);
            mp2.clear();
            for(auto it:mp1){
                mp2[__gcd(it.first,a[i])]+=it.second;
            }
            mp2[a[i]]++;
            for(auto it:mp2){
                ans[it.first]+=it.second;
            }
        }
        int q;cin>>q;while(q--)
        {
            int x;
            scanf("%d",&x);
            printf("%lld\n",ans[x]);
        }
    }
发布了498 篇原创文章 · 获赞 66 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41286356/article/details/104916820