小米 OJ 编程比赛 03 月常规赛

A.数学等式

数据比较小,可以暴力+折半枚举。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=200010;
map<int,int>mp;
int main()
{
    int N,A,B,C,D,E; ll ans=0;
    scanf("%d%d%d%d%d",&A,&B,&C,&D,&E);
    rep(i,-50,50)
     rep(j,-50,50)
      rep(k,-50,50){
        if(i*j*k==0) continue;
        int x=A*i*i*i+B*j*j*j+C*k*k*k;
        mp[x]++;
    }
    rep(i,-50,50)
     rep(j,-50,50){
       if(i*j==0) continue;
       int x=D*i*i*i+E*j*j*j;
       ans+=mp[x];
    }
    printf("%lld\n",ans);
    return 0;
}

B.贪吃的细胞

最小生成树,即是S和所有的营养液连通,我们把S和营养液看成关键点,那么预处理出关键点之间的两两距离(BFS即可)。

然后从S开始,跑基于prim的最小生成树。 题中,我们需要加限制,即如果A->B要连边(A处一个细胞到B处),那么A的细胞数不能为0,而一个细胞跑到B后,变为c[B]+1个,同时用B到其他点的距离更新最小距离。

(由于std出了问题,我们先假设代码是对的。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=210;
const int inf=1000000;
char c[maxn][maxn];
int id[maxn][maxn],vis[maxn][maxn],X[maxn],Y[maxn],Z[maxn];
int T,N,M,tot,Sx,Sy,num;
int peo[maxn],used[maxn],Dis[maxn][maxn],ans;
int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
int dis[maxn][maxn][maxn],qx[maxn*maxn],qy[maxn*maxn],head,tail;
struct in{
    int id,dis,from;
    in(){}
    in(int ii,int dd,int ff):id(ii),dis(dd),from(ff){}
    friend bool operator <(in w,in v){
        return w.dis>v.dis;
    }
};
priority_queue<in>q;
void dfs1(int x,int y)
{
    if(x<1||x>N||y<1||y>M||vis[x][y]||c[x][y]==‘#‘) return ;
    vis[x][y]=1; if(c[x][y]>=‘1‘&&c[x][y]<=‘9‘) num++;
    rep(i,0,3) dfs1(x+xx[i],y+yy[i]);
}
void get(int p) //得到关键点和其他关键点的距离
{
    rep(i,1,N) rep(j,1,M) dis[p][i][j]=inf;
    rep(i,1,tot) Dis[p][i]=inf;
    head=tail=0; head++;
    qx[head]=X[p],qy[head]=Y[p]; dis[p][X[p]][Y[p]]=0;
    while(tail<head){
        tail++;
        int tx=qx[tail],ty=qy[tail];
        rep(i,0,3){
            int rx=tx+xx[i],ry=ty+yy[i];
            if(rx>=1&&rx<=N&&ry>=1&&ry<=M&&c[rx][ry]!=‘#‘&&dis[p][rx][ry]==inf){
                dis[p][rx][ry]=dis[p][tx][ty]+1;
                if(id[rx][ry]) Dis[p][id[rx][ry]]=dis[p][rx][ry];
                head++; qx[head]=rx; qy[head]=ry;
            }
        }
    }
}
void solve()
{
    rep(i,0,tot) get(i);
    rep(i,1,tot) peo[i]=used[i]=0;
    peo[0]=1; ans=0; int sz=0; used[0]=1;
    rep(i,1,tot) if(Dis[0][i]!=inf){
        q.push(in(i,Dis[0][i],0));  //sz++;
    }
    while(!q.empty()){  //每次贪心的找最小边
        in t=q.top(); q.pop();
        if(t.id&&peo[t.from]&&!used[t.id]){
            peo[t.from]--; used[t.id]=1; ans+=t.dis;
            peo[t.id]+=1+Z[t.id]; sz++;
            rep(i,1,tot) if(!used[i]&&Dis[t.id][i]!=inf){ //来源有多的细胞,且目的地没有被用掉,则合法
               q.push(in(i,Dis[t.id][i],t.id));
            }
        }
    }
}
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        rep(i,1,N) scanf("%s",c[i]+1);
        tot=num=0;
        rep(i,1,N) rep(j,1,M) id[i][j]=vis[i][j]=0;
        rep(i,1,N)
         rep(j,1,M){
             if(c[i][j]>=‘1‘&&c[i][j]<=‘9‘) {
                id[i][j]=++tot;
                X[tot]=i; Y[tot]=j; Z[tot]=c[i][j]-‘0‘;
             }
             else if(c[i][j]==‘S‘||c[i][j]==‘s‘) X[0]=Sx=i,Y[0]=Sy=j;
        }
        dfs1(Sx,Sy);
        if(num!=tot){ puts("-1"); continue;}
        solve();
        printf("%d\n",ans);
    }
    return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=210;
const int inf=1000000;
char c[maxn][maxn];
int id[maxn][maxn],vis[maxn][maxn],X[maxn],Y[maxn],Z[maxn];
int T,N,M,tot,Sx,Sy,num;
int peo[maxn],used[maxn],Dis[maxn][maxn],ans;
int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1};
int dis[maxn][maxn][maxn],qx[maxn*maxn],qy[maxn*maxn],head,tail;
struct in{
    int id,dis,from;
    in(){}
    in(int ii,int dd,int ff):id(ii),dis(dd),from(ff){}
    friend bool operator <(in w,in v){
        return w.dis>v.dis;
    }
};
priority_queue<in>q;
void dfs1(int x,int y)
{
    if(x<1||x>N||y<1||y>M||vis[x][y]||c[x][y]==‘#‘) return ;
    vis[x][y]=1; if(c[x][y]>=‘1‘&&c[x][y]<=‘9‘) num++;
    rep(i,0,3) dfs1(x+xx[i],y+yy[i]);
}
void get(int p)
{
    rep(i,1,N) rep(j,1,M) dis[p][i][j]=inf;
    rep(i,1,tot) Dis[p][i]=inf;
    head=tail=0; head++;
    qx[head]=X[p],qy[head]=Y[p]; dis[p][X[p]][Y[p]]=0;
    while(tail<head){
        tail++;
        int tx=qx[tail],ty=qy[tail];
        rep(i,0,3){
            int rx=tx+xx[i],ry=ty+yy[i];
            if(rx>=1&&rx<=N&&ry>=1&&ry<=M&&c[rx][ry]!=‘#‘&&dis[p][rx][ry]==inf){
                dis[p][rx][ry]=dis[p][tx][ty]+1;
                if(id[rx][ry]) Dis[p][id[rx][ry]]=dis[p][rx][ry];
                head++; qx[head]=rx; qy[head]=ry;
            }
        }
    }
}
void solve()
{
    rep(i,0,tot) get(i);
    rep(i,1,tot) peo[i]=used[i]=0;
    peo[0]=1; ans=0; int sz=0; used[0]=1;
    rep(i,1,tot) if(Dis[0][i]!=inf){
        q.push(in(i,Dis[0][i],0));  //sz++;
    }
    while(!q.empty()){
        in t=q.top(); q.pop();
        if(t.id&&peo[t.from]&&!used[t.id]){
            peo[t.from]--; used[t.id]=1; ans+=t.dis;
            peo[t.id]+=1+Z[t.id]; sz++;
            rep(i,1,tot) if(!used[i]&&Dis[t.id][i]!=inf){
               q.push(in(i,Dis[t.id][i],t.id));
            }
        }
    }
}
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        rep(i,1,N) scanf("%s",c[i]+1);
        tot=num=0;
        rep(i,1,N) rep(j,1,M) id[i][j]=vis[i][j]=0;
        rep(i,1,N)
         rep(j,1,M){
             if(c[i][j]>=‘1‘&&c[i][j]<=‘9‘) {
                id[i][j]=++tot;
                X[tot]=i; Y[tot]=j; Z[tot]=c[i][j]-‘0‘;
             }
             else if(c[i][j]==‘S‘||c[i][j]==‘s‘) X[0]=Sx=i,Y[0]=Sy=j;
        }
        dfs1(Sx,Sy);
        if(num!=tot){ puts("-1"); continue;}
        solve();
        printf("%d\n",ans);
    }
    return 0

C.小爱密码 2.0

一看就是规律题,打出前面几个,发现除了前面两个其他的下标都是素数,那么我们素数筛得到所有对应的fib下标即可。 然后针对问题,我们矩阵乘法得到对应的答案,然后exgcd求逆元。(m不是素数,不能快速幂求逆元。

打表代码:

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=7500010;
ll a[40];
int main()
{
    a[3]=2; a[4]=3;
    rep(i,5,30) a[i]=a[i-1]+a[i-2];
    rep(i,3,30){
        int f=0;
        rep(j,3,i-1) if(a[i]%a[j]==0) f=1;
        if(!f) cout<<i<<" ";
    }
    return 0;
}

矩阵快速幂代码:

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=7500010;
bool vis[maxn]; int p[500010],cnt,Mod;
void prime()
{
    for(int i=2;i<maxn;i++){
        if(!vis[i]){
            p[++cnt]=i;
            if(cnt==500000) break;
        }
        for(int j=1;j<=cnt&&i*p[j]<maxn;j++){
            vis[i*p[j]]=1;
            if(i%p[j]==0) break;
        }
    }
}
struct mat{
    int m[2][2];
    mat(){memset(m,0,sizeof(m));}
    friend mat operator *(mat a,mat b){
        mat res;
        rep(i,0,1)
         rep(j,0,1)
          rep(k,0,1) (res.m[i][j]+=1LL*a.m[i][k]*b.m[k][j]%Mod)%=Mod;
        return res;
    }
    friend mat operator ^(mat a,int x){
        mat res; res.m[0][0]=res.m[1][1]=1;
        while(x){
            if(x&1) res=res*a; a=a*a; x>>=1;
        } return res;
    }
};
int getfib(int N)
{
    mat ans,base;
    ans.m[0][0]=ans.m[1][0]=1;
    base.m[0][0]=base.m[0][1]=base.m[1][0]=1;
    ans=(base^(N-2))*ans;
    return ans.m[0][0];
}
void exgcd(int a,int b,int d,int &x,int &y)
{
    if(b==0){ d=a; x=1; y=0; return;}
    exgcd(b,a%b,d,y,x); y-=a/b*x;
}
int rev(int a,int b)
{
    int x,y,d;
    exgcd(a,b,d,x,y); return (x+b)%b;
}
int main()
{
    prime(); int N;
    p[1]=3; p[2]=4;
    while(~scanf("%d%d",&N,&Mod)){
        N=p[N];
        int ans=getfib(N);
        ans=1LL*ans*rev(3,Mod)%Mod;
        int L=0,x=ans;
        while(x){ x/=10; L++;}
        if(ans==0) L++;
        rep(i,1,9-L) putchar(‘*‘);
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/10625322.html

时间: 2024-07-30 17:05:56

小米 OJ 编程比赛 03 月常规赛的相关文章

小米 OJ 编程比赛 12 月常规赛

小米兔跳格子 序号:#119难度:一般时间限制:1000ms内存限制:30M 描述 米兔爸爸为了让小米兔好好锻炼身体,便给小米兔设置了一个挑战——跳格子. 要吃到自己心爱的胡萝卜,小米兔需要跳过面前一些格子.现有 NN 个格子,每个格子内都写上了一个非负数,表示当前最多可以往前跳多少格,胡萝卜就放在最后一个格子上.米兔开始站在第 1 个格子,试判断米兔能不能跳到最后一个格子吃到胡萝卜呢? 输入 输入为 NN 个数字 (N \lt 10N<10),用空格隔开,第 ii 个数字 s_isi? (0

网易云课堂_C++程序设计入门(下)_第10单元:月映千江未减明 – 模板_第10单元 - 单元作业:OJ编程 - 创建数组类模板

第10单元 - 单元作业:OJ编程 - 创建数组类模板 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 本单元作业练习创建模板类.单元作业会涉及冒泡排序.线性查找等算法.如果对排序.查找不熟悉,可以自行baidu或者google 依照学术诚信条款,我保证此作业是本人独立完成的. 1 编写一个数组类模板 Array,能够存储不同类型的数组元素.对数组元素进行查找.

专访北京航空航天大学黎健成:我和编程比赛

前言: 在对黎健成采访的过程中,他始终强调自己是一名普通的学生,不能和曹鹏博士那样的刷题大牛相比,他接受采访是为了和更多的同学交流探讨.笔者认为,一个在各类活动中能够取得优异成绩的学生,一定在课余时间付出大量时间进行练习和复习,大量刷题和阅读技术书籍."天道酬勤",虽然天资重要,但是更离不开勤奋与努力.黎健成认为自己取得成绩,更多是通过努力付出得到的. 黎健成,北京航空航天大学软件工程专业的大四学生.除了正常上课学习外,积极参加课外竞赛活动,在竞赛活动中不断学习成长.曾获得ACM-IC

网易云课堂_C++程序设计入门(下)_第7单元:出入虽同趣,所向各有宜 – 文件输入和输出_第7单元 - 作业1:OJ编程

第7单元 - 作业1:OJ编程 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 本作业是第7单元作业系列. 本单元[多个作业]之间有[前后依赖关系]. 本单元作业应[按照次序]完成. 依照学术诚信条款,我保证此作业是本人独立完成的. 1 阅读所给的代码,理解代码的主要功能及原理 补充缺失代码 提交OJ判分(10分) 题目内容: 以单例模式创建一个屏幕Screen

网易云课堂_C++程序设计入门(下)_第11单元:工欲善其事必先利其器 - STL简介_第11单元 - 单元作业1:OJ编程 - vector 与 sort

第11单元 - 单元作业1:OJ编程 - vector 与 sort 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 本次作业练习使用 vector 容器以及 sort 算法,对输入的数据进行排序 依照学术诚信条款,我保证此作业是本人独立完成的. 1 本次作业练习使用 vector 容器以及 sort 算法,对输入的数据进行排序(5分) 题目的具体内容参见 [第

网易云课堂_C++程序设计入门(下)_第8单元:年年岁岁花相似– 运算符重载_第8单元 - 作业2:OJ编程 - 重载数组下标运算符

第8单元 - 作业2:OJ编程 - 重载数组下标运算符 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 练习数组下标运算符重载 依照学术诚信条款,我保证此作业是本人独立完成的. 1 练习数组下标运算符重载(6分) 本题目具体内容请参见 [第8单元 - 单元作业2说明] 时间限制:500ms内存限制:32000kb #include <iostream> #in

四川大学线下编程比赛第三题:书本转移

好久没写过日志,也怪最近事情真的特别多,最近参加关于编程方面就是CSDN高校俱乐部举办的线下编程塞,说起这次编程赛,总共三道题,题目都可以在csdn高校俱乐部上看到,参加比赛的时候有点小紧张,第三题涉及到队列,当时的机器没有代码提示,坑...也怨自己平时写代码用惯了代码提示,很多stl的方法都是隐隐约约知道,但是具体的不知道,导致第三题没有做出来,遗憾哈!下面贴一下今天写的第三题的代码 题目 四川大学线下编程比赛第三题:书本转移 题目详情: 小强有 3 个箱子 A,B,C 用来装书,所有的书(一

2014华为编程比赛-筷子问题

//华为编程:筷子,找到第一个单对的筷子 #include <stdio.h> #define max 37 int main() { int n,i,j; int a[max]; int flag=0; int error=-1; scanf("%d",&n); if(n>max) { printf("%d\n",error); return error; } for(i=0;i<n;i++) scanf("%d"

网易云课堂_C++程序设计入门(下)_第9单元:白公曾咏牡丹芳,一种鲜妍独“异常”_第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理

第9单元 - 作业5:OJ编程 - 使用异常进行图形类的错误处理 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 基于第8单元的作业内容,为图形类添加异常处理代码 依照学术诚信条款,我保证此作业是本人独立完成的. 1 基于第8单元作业2的代码,为图形类添加异常处理的代码.(5分) 题目具体内容参见: 第9单元 - 作业5说明:[OJ - 使用异常进行图形类的错误