zoukankan      html  css  js  c++  java
  • 9.18 正睿 CSP 七连测 day4

    T1

    诈骗题,这个题看着挺吓人,实际上没有这么吓人。我们只需要对这个矩阵进行分割即可,分割成不相等的 (3 imes 3) 的小格子,加起来即可。代码:

    #include<bits/stdc++.h>
    #define dd double
    #define ld long double
    #define ll long long
    #define uint unsigned int
    #define ull unsigned long long
    #define N 201
    #define M 201
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    
    template<typename T> inline void read(T &x) {
        x=0; int f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    int a[N][N],n,m,ans;
    const int Begin[]={2,1,2};
    
    inline int Get(){
        char c=getchar();for(;!isdigit(c);c=getchar());
        return c-'0';
    }
    
    int main(){
        read(n);read(m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]=Get();
            }
        }
        for(int i=Begin[n%3];i<=n;i+=3){
            for(int j=Begin[m%3];j<=m;j+=3){
                ans+=a[i][j];
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    

    T2

    这个题还是比较巧妙地,巧妙的地方在于用并查集,然后把整个问题转换为连通块合并,所以最终的答案就是连通块的个数。这个建模比较巧妙,其切入点在于整个题目与行和列的相关性。

    代码:

    #include<bits/stdc++.h>
    #define dd double
    #define ld long double
    #define ll long long
    #define uint unsigned int
    #define ull unsigned long long
    #define N 1010
    #define M number
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    
    template<typename T> inline void read(T &x) {
        x=0; int f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    struct DSU{
        int fa[N<<1],size[N<<1];
        inline void Init(int n){for(int i=1;i<=n;i++) fa[i]=i,size[i]=1;}
        inline int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);}
        inline bool Merge(int a,int b){
            int faa=Find(a),fab=Find(b);if(faa==fab) return 0;if(size[faa]<size[fab]) swap(faa,fab);
            fa[fab]=faa;size[faa]+=size[fab];return 1;
        }
        inline int GetAns(int n){
            int res=0;
            for(int i=1;i<=n;i++) if(fa[i]==i) res++;
            return res;
        }
    }dsu;
    
    int n,m,a[N][N],ans,num;
    
    inline int GetInt(){
        char c=getchar();for(;!isdigit(c);c=getchar());
        return c-'0';
    }
    
    int main(){
        read(n);read(m);dsu.Init(n+m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                a[i][j]=GetInt();
                if(a[i][j]) dsu.Merge(i,j+n);else num++;
            }
        int now=dsu.GetAns(n+m);
        ans=(now-1)*4+(num-now+1)*3;
        // printf("now:%d
    ",now);
        printf("%d
    ",ans);
        return 0;
    }
    

    T3

    我们考虑先想这个题目的简单情况,如果给定的这条直线是一条竖直的直线怎么做,不难发现,如果我们把所有点映射到 (x) 轴上,那么答案一定存在于相邻两个点之间的斜率。

    所以我们考虑把所有点映射到 (-frac{Q}P) 上,这个东西等价于我们算出这个点在这个斜率下的在 (y) 轴上的截距。枚举即可。代码:

    #include<bits/stdc++.h>
    #define dd double
    #define ld long double
    #define ll long long
    #define int long long
    #define uint unsigned int
    #define ull unsigned long long
    #define N 1000100
    #define M number
    using namespace std;
    
    const int INF=1e9+7;
    
    template<typename T> inline void read(T &x) {
        x=0; int f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    int n,P,Q,fenzi=1,fenmu;
    dd K,cha=INF;
    
    struct Point{
        int x,y;
        inline Point(){}
        inline Point(int x,int y) : x(x),y(y) {}
        inline bool operator < (const Point &b) const{
            return -x*P+y*Q<-b.x*P+b.y*Q;
        }
    }p[N];
    
    inline dd CalcK(Point a,Point b){
        if(a.x==b.x) return INF;
        return (dd)(b.y-a.y)/(dd)(b.x-a.x);
    }
    
    inline int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    
    signed main(){
        read(n);read(P);read(Q);
        for(int i=1;i<=n;i++){read(p[i].x);read(p[i].y);}
        sort(p+1,p+n+1);K=(dd)P/(dd)Q;
        for(int i=1;i<=n-1;i++){
            dd nowk=CalcK(p[i],p[i+1]);
            dd nowcha=fabs(nowk-K);
            if(nowcha<cha){
                cha=nowcha;fenzi=abs(p[i+1].y-p[i].y);fenmu=abs(p[i+1].x-p[i].x);
            }
        }
        int g=gcd(fenzi,fenmu);
        printf("%d/%d
    ",fenzi/g,fenmu/g);
        return 0;
    }
    

    T4

    不难想到 dp,我们设 (f_{i,j}) 表示考虑把 (j) 个任务分给前 (i) 个人其中满足至少一个人高兴的方案数。那么首先,我们可以让 (f_{i,j}=dbinom{j}{i}(j-i)^{i-1}),表示我让第 (i) 个人开心,其余人随意,否则我们枚举第 (i) 个人拿多少任务,从前面转移过来。注意第一个赋值是有条件的。代码:

    #include<bits/stdc++.h>
    #define dd double
    #define ld long double
    #define ll long long
    #define uint unsigned int
    #define ull unsigned long long
    #define N 360
    #define M number
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int mod=1e9+7;
    
    template<typename T> inline void read(T &x) {
        x=0; int f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    int f[N][N],n,c[N][N];
    
    inline int ksm(int a,int b,int mod){
        int res=1;while(b){if(b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}return res;
    }
    
    inline void PreWork(){
        for(int i=0;i<=n;i++)
            for(int j=0;j<=i;j++){
                if(j==0||j==i) c[i][j]=1;
                else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
            }
    }
    
    int main(){
        read(n);PreWork();
        for(int i=1;i<=n;i++){
            for(int j=0;j<=n;j++){
                if(j>=i){f[i][j]=1ll*ksm(i-1,j-i,mod)*c[j][i]%mod;}
                // printf("i:%d j:%d f:%d
    ",i,j,f[i][j]);
                for(int k=0;k<=j;k++){
                    // printf("k:%d
    ",k);
                    if(k==i) continue;
                    f[i][j]=(f[i][j]+1ll*f[i-1][j-k]*c[j][k]%mod)%mod;
                    // printf("i:%d j:%d f:%d
    ",i,j,f[i][j]);
                    // printf("i:%d j:%d c:%d
    ",i,j,c[i][j]);
                }
                // printf("i:%d j:%d f:%d
    ",i,j,f[i][j]);
            }
        }
        printf("%d
    ",f[n][n]);
        return 0;
    }
    
  • 相关阅读:
    Flask之模型字段解析与OA建模实训
    CentOS7下部署Django项目详细操作步骤
    多线程爬虫之生产者和消费者模式
    Flask的函数视图与类视图
    经典算法题之约瑟夫环与全排列
    selenium之滑块验证码破解代码详解
    基于CentOS7的MySQL数据库主从备份
    CentOS7下部署Flask项目部署
    selenium的学习和使用
    缓冲区溢出
  • 原文地址:https://www.cnblogs.com/TianMeng-hyl/p/15339652.html
Copyright © 2011-2022 走看看