• 2020年浙江理工大学校赛同步赛


    题目
    A题意:定义一个自然数,若它的质因数至少是两重的,则称为漂亮数,若相邻两个自然数都是“漂亮数”, 就称它们为“孪生漂亮数”。输出[n,m]区间所有孪生漂亮数。
    解法:类似质因数分解,如果存在某一质因数判断该质因数是否是两个以上。

    int n , m ;
    
    bool eluer(int x){
        rep(i , 2 , sqrt(x)){
            if(x % i == 0){
                int cnt = 0 ;
                while(x % i == 0){
                    x /= i ;
                    cnt++;
                }
                if(cnt == 1) return false;
            }
        }
        if(x > 1) return false;
        return true;
    }
    
    void solve(){
        scanf("%lld%lld" , &n , &m);
        vector<int>a;
        rep(i , n , m){
            if(eluer(i)){
                a.pb(i);
            }
        }
        int flag = 0 ;
        for(int i = 1 ; i < size(a) ; i++){
            if(a[i] - a[i-1] == 1){
                flag = 1 ;
                cout << a[i-1] << " " << a[i] << endl;
            }
        }
        if(!flag){
            cout << "no find" << endl;
        }
    }
    

    B题意:给出n列2行格子,在格子中填0-9中任意数,问满足任意相邻3列总和为k的填法。
    解法:枚举前三列的取值,确定了前三列的取值,之后列取值也随之确定。

    const int maxn = 1e5+9;
    int a[maxn][3];
    int b[4] , c[4];//记录前三个列的和以及方案数
    
    pii get(int i){//获取第i列的范围
        if(a[i][0] == -1 && a[i][1] == -1) return {0,18};
        if(a[i][0] != -1 && a[i][1] != -1) return {a[i][0] + a[i][1] , a[i][0] + a[i][1]};
        return {a[i][0] + a[i][1] + 1 , a[i][0] + a[i][1] + 10};
    }
    int solve(int i , int j){//i列和等于j的方案数
        if(a[i][0] == -1 && a[i][1] == -1){
            if(j >= 0 && j <= 9){
                return j+1;
            }else if(j != 18){
                return 10 - j % 9 ;
            }else{
                return 1;
            }
        }else{
            return 1 ;
        }
    }
    
    void solve(){
        ME(a , -1);
        int n , sum , m ;
        scanf("%lld%lld%lld" , &n , &sum , &m);
        rep(i , 1 , m){
            int x , y , w ;
            scanf("%lld%lld%lld" , &x , &y , &w);
            a[x][y] = w ;
        }
        pii x = get(0) , y = get(1) , z = get(2);
        int ans = 0 ;
        rep(i , x.fi , x.se){//枚举第一列范围
            b[0] = i ;
            c[0] = solve(0 , i);
            rep(j , y.fi , y.se){//枚举第二列范围
                b[1] = j ;
                c[1] = solve(1 , j);
                int k = sum - i - j ;//根据总和确定第三列值
                if(k > z.se || k < z.fi) continue;//判断是否在第三列的范围当中
                b[2] = k ;
                c[2] = solve(2 , k);
                int res = c[0] * c[1] * c[2] ;//前三列的种数
                rep(l , 3 , n-1){
                    pii p = get(l);//获取第l列取值范围
                    if(b[l%3] < p.fi || b[l%3] > p.se){//第四列与第一列和一致,第一列取值是否在l列的取值范围内
                        res = 0 ;
                        break;
                    }
                    res = (res * solve(l , b[l%3]))%  mod ;
                }
                ans  = (ans + res) % mod ;
            }
        }
        cout << ans << endl;
    }
    

    C题意:模拟。

    const int N = 4e2+9;
    const int maxn = 29;
    int t , n , m ;
    struct grid{
        int t , d ;//土地类型和土壤时间
    }g[maxn][maxn];
    int sl , wl;//羊和狼的数量
    struct Sheep{
        int x , y , d , l;//羊的坐标、饥饿度,是否存活
    }s[N];
    struct Wolf{
        int x , y , d , l;//同上
    }w[N];
    
    void cow(){//土壤长草
        rep(i , 1 , n){
            rep(j , 1 , m){
                if(g[i][j].t == 3){//土壤类型
                    g[i][j].d++;
                    if(g[i][j].d > 3){//坑点1:三天后长草
                        g[i][j].t = 2 ;
                    }
                }
            }
        }
    }
    void sw_move(){//羊移动、狼移动
        rep(i , 1 , sl){
            if(s[i].l == 1){//存活的羊
                s[i].x++;
                if(s[i].x == n+1) s[i].x = 1 ;
                s[i].d++;//羊饥饿度增加
            }
        }
        rep(i , 1 , wl){
            if(w[i].l == 1){//存活的狼
                w[i].y++;
                if(w[i].y == m+1) w[i].y = 1 ;
                w[i].d++;//狼的饥饿度增加
            }
        }
    }
    
    void eatsheep(){//羊吃狼
        rep(i , 1 , sl){
            rep(j , 1 , wl){
                if(s[i].l == 1 && w[j].l == 1 && s[i].x == w[j].x && s[i].y == w[j].y){//羊和狼位于同一土壤
                    s[i].l = 0 ;//狼吃羊
                    g[s[i].x][s[i].y].t = 1 ;//该地变为残骸
                    w[j].d = 0 ;
                }
            }
        }
        rep(i , 1 , wl){
            if(w[i].l == 1){
                if(w[i].d>=10){//狼饿死
                    w[i].l = 0 ;
                    g[w[i].x][w[i].y].t = 1 ;
                }
            }
        }
    }
    
    void eatcow(){//羊吃草
        rep(i , 1 , sl){
            if(s[i].l == 1){
                int x = s[i].x , y = s[i].y ;
                if(g[x][y].t == 2){//羊吃草
                    s[i].d = 0 ;
                    g[x][y].t = 3 ;
                    g[x][y].d = 0;
                }else{
                    if(s[i].d >= 5){//羊饿死
                        s[i].l = 0 ;
                        g[x][y].t = 1 ;
                    }
                }
            }
        }
    }
    void turn(){//坑点2
        rep(i , 1 , n){
            rep(j , 1 , m){
                if(g[i][j].t == 3 && g[i][j].d >= 3){//T天后土壤状态是否长草
                    g[i][j].t = 2;
                }
            }
        }
    }
    
    void solve(){
         scanf("%lld%lld%lld" , &t , &n , &m);
         rep(i , 1 , n){
             rep(j , 1 , m){
                 char c ;
                 cin >> c;
                 g[i][j].t = 3 , g[i][j].d = 0 ;//初始都为土壤
                 if(c == 'S'){
                     s[++sl].x = i , s[sl].y = j , s[sl].d = 0 , s[sl].l = 1;
                 }else if(c == 'W'){
                     w[++wl].x = i , w[wl].y = j , w[wl].d = 0 , w[wl].l = 1;
                 }
             }
         }
         rep(i , 1 , t){
             cow();
             sw_move();
             eatsheep();
             eatcow();
         }
         turn();
         set<pii>sh , wo;
         rep(i , 1 , sl){//记录存活的羊的坐标
             if(s[i].l == 1){
                 sh.insert(mp(s[i].x , s[i].y));
             }
         }
         rep(i, 1 , wl){//记录存活的狼的坐标
             if(w[i].l == 1){
                 wo.insert(mp(w[i].x , w[i].y));
             }
         }
         rep(i , 1 , n){
             rep(j , 1 , m){
                 if(sh.count(mp(i , j))){//该坐标存在羊
                     printf("S");
                 }else if(wo.count(mp(i , j))){//该坐标存在狼
                     printf("W");
                 }else if(g[i][j].t == 1){
                     printf("*");
                 }else if(g[i][j].t == 2){
                     printf("#");
                 }else{
                     printf(".");
                 }
             }
             printf("
    ");
         }
    }
    

    D题意:求圆与矩形相交的面积。
    https://www.cnblogs.com/qywhy/p/9772681.html

    #include<bits/stdc++.h>
    #define inf 1000000000000
    #define M 100009
    #define eps 1e-12
    #define PI acos(-1.0)
    using namespace std;
    struct Point
    {
        double x,y;
        Point(){}
        Point(double xx,double yy){x=xx;y=yy;}
        Point operator -(Point s){return Point(x-s.x,y-s.y);}
        Point operator +(Point s){return Point(x+s.x,y+s.y);}
        double operator *(Point s){return x*s.x+y*s.y;}
        double operator ^(Point s){return x*s.y-y*s.x;}
    }p[M];
    double max(double a,double b){return a>b?a:b;}
    double min(double a,double b){return a<b?a:b;}
    double len(Point a){return sqrt(a*a);}
    double dis(Point a,Point b){return len(b-a);}//两点之间的距离
    double cross(Point a,Point b,Point c)//叉乘
    {
        return (b-a)^(c-a);
    }
    double dot(Point a,Point b,Point c)//点乘
    {
        return (b-a)*(c-a);
    }
    int judge(Point a,Point b,Point c)//判断c是否在ab线段上(前提是c在直线ab上)
    {
        if (c.x>=min(a.x,b.x)
           &&c.x<=max(a.x,b.x)
           &&c.y>=min(a.y,b.y)
           &&c.y<=max(a.y,b.y)) return 1;
        return 0;
    }
    double area(Point b,Point c,double r)
    {
        Point a(0.0,0.0);
        if(dis(b,c)<eps) return 0.0;
        double h=fabs(cross(a,b,c))/dis(b,c);
        if(dis(a,b)>r-eps&&dis(a,c)>r-eps)//两个端点都在圆的外面则分为两种情况
        {
            double angle=acos(dot(a,b,c)/dis(a,b)/dis(a,c));
            if(h>r-eps) return 0.5*r*r*angle;else
            if(dot(b,a,c)>0&&dot(c,a,b)>0)
            {
                double angle1=2*acos(h/r);
                return 0.5*r*r*fabs(angle-angle1)+0.5*r*r*sin(angle1);
            }else return 0.5*r*r*angle;
        }else
            if(dis(a,b)<r+eps&&dis(a,c)<r+eps) return 0.5*fabs(cross(a,b,c));//两个端点都在圆内的情况
            else//一个端点在圆上一个端点在圆内的情况
            {
                if(dis(a,b)>dis(a,c)) swap(b,c);//默认b在圆内
                if(fabs(dis(a,b))<eps) return 0.0;//ab距离为0直接返回0
                if(dot(b,a,c)<eps)
                {
                    double angle1=acos(h/dis(a,b));
                    double angle2=acos(h/r)-angle1;
                    double angle3=acos(h/dis(a,c))-acos(h/r);
                    return 0.5*dis(a,b)*r*sin(angle2)+0.5*r*r*angle3;
                }else
                {
                    double angle1=acos(h/dis(a,b));
                    double angle2=acos(h/r);
                    double angle3=acos(h/dis(a,c))-angle2;
                    return 0.5*r*dis(a,b)*sin(angle1+angle2)+0.5*r*r*angle3;
                }
            }
    }
    int main()
    {
        int T,n=4;
        double rx,ry,R;
        //scanf("%d",&T);
        //for (int ii=1;ii<=T;ii++)
        //{
            scanf("%lf%lf%lf",&rx,&ry,&R);
            scanf("%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[3].x,&p[3].y);
            p[2].x=p[1].x;p[2].y=p[3].y;
            p[4].x=p[3].x;p[4].y=p[1].y;
            p[5]=p[1];
            Point O(rx,ry);
            for (int i=1;i<=n+1;i++) p[i]=p[i]-O;
            O=Point(0,0);
            double sum=0;
            for (int i=1;i<=n;i++)
            {
                int j=i+1;
                double s=area(p[i],p[j],R);
                if (cross(O,p[i],p[j])>0) sum+=s;else sum-=s;
            }
            printf("%.4lf
    " , fabs(sum));
        //}
        return 0;
    }
    

    E题意:在一条直线上给出n个摊位的坐标,要使的任意两个摊位的坐标距离正好是k米,问摊位最少移动距离为多少。
    解法:中位数原理,所有摊位向中位数靠拢。

    int n , m ;
    void solve(){
        int n , k ;
        scanf("%lld%lld" , &n , &k);
        vector<int>a(n);
        rep(i , 0 , n-1){
            cin >> a[i];
        }
        sort(all(a));
        int mid = size(a)/2;
        int t = mid-1 , d = a[mid]-k , sum = 0;//摊位下标,该摊位该去的位置
        while(t>=0){
            sum += abs(d-a[t]);
            d -= k ;
            t--;
        }
        t = mid + 1 , d = a[mid]+k ;
        while(t < size(a)){
            sum += abs(d-a[t]);
            d += k ;
            t++;
        }
        cout << sum << endl;
    }
    
  • 相关阅读:
    因为公司项目需要,我要学习PB了,哎
    送给自己人生的第一份生日礼物——Java小游戏!
    第二讲 Java 开发环境搭建
    IT学生关于“怎么学习”的思考,这也是其他人思考的问题吗?
    第四讲 类与对象
    第一讲 Java 介绍
    第三讲 Java 基本数据类型+运算符
    初步理解Lambda表达式的简单实现
    一道关于pack()和sizeof笔试题
    排序源码(待续)
  • 原文地址:https://www.cnblogs.com/nonames/p/13181482.html
Copyright © 2020-2023  润新知