浙江农林大学第十九届程序设计竞赛暨天梯赛选拔赛部分题题解

A.锯锯锯锯锯锯锯锯

题目传送门
锯锯锯锯锯锯

题意见题干

思路:

如果每输入一组数据就进行一次运算的话,肯定会超时。那么我们可以把所有数据先输入,然后对每个数据进行标记。然后把输入的数据进行排序。循环1到1e8,如果输入的数据被遍历到了就记录答案。最后计算即可。(比赛的时候怎么没想到呢,可恶!!!)

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10,mod=1e9+7;
map<int,bool>mp;
map<int,LL>mmp;
int a[N],b[N],cnt=0;
int f[N*2];
LL quick_pow(LL x,LL y)
{
    
    
    LL res=1;
    while(y)
    {
    
    
        if(y%2) res=res*x%mod;
        y=y/2;
        x=x*x%mod;
    }
    return res;
}
int main()
{
    
    
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%d%d",&a[i],&b[i]);
        mp[a[i]]=1;
        mp[b[i]]=1;
        f[++cnt]=a[i];
        f[++cnt]=b[i];
    }
    sort(f+1,f+1+cnt);
    LL x=1;
    mmp[0]=1;
    int k=1;
    for(int i=1;i<=1e8;i++)
    {
    
    
        x=(x*x+x)%mod;
        while(f[k]<i&&k<=cnt) k++;
        if(f[k]==i) mmp[i]=x;
    }
    for(int i=1;i<=n;i++)
    {
    
    
        if(a[i]<b[i]) swap(a[i],b[i]);
        LL res=mmp[a[i]]*quick_pow(mmp[b[i]],mod-2)%mod;
        printf("%lld\n",res);
    }
    system("pause");
    return 0;
}

B.每日咕咚

题目传送门

每日咕咚

题意见题干

思路:

每个同学在每个位置的概率都为1/n,那么简单求期望就好。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    
    
    int n;
    double x,v;
    scanf("%d%lf%lf",&n,&x,&v);
    double dis=n*x;
    double ans=0;
    for(int j=1;j<=n;j++)
    {
    
    
        for(int i=1;i<=n;i++)
        {
    
    
            double y;
            scanf("%lf",&y);
            ans=ans+dis/(y-v);
        }
    }
    printf("%.2f",ans/n);
    //system("pause");
    return 0;
}

D.涛涛和策策的游戏

题目传送门:
涛涛和策策的游戏

题意见题干

思路:

比赛时读错了题意,我本以为因数也需要是给出的数字,打完再读了一遍,发现只要是被选出数字的因数即可(我是菜逼)。然后题目就转化为了简单的尼姆博弈。算出每个数的质因子数量,然后进行异或即可。异或结果是1则策策赢,否则涛涛赢。

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=1e6+10;
int a[N];
int idx=0,primes[M],ans[M];
int sum[N];
void solve(int num)
{
    
    
    int k=1;
    int p=a[num];
    while(primes[k]*primes[k]<=p)
    {
    
    
        while(p%primes[k]==0)
        {
    
    
            sum[num]++;
            p=p/primes[k];
        }
        k++;
    }
    if(p>1) sum[num]++;
}
int main()
{
    
    
    int n;
    scanf("%d",&n);
    for(int i=2;i<=M;i++)
    {
    
    
        if(ans[i]==0) primes[++idx]=i;
        for(int j=1;j<=idx&&i*primes[j]<=M;j++)
        {
    
    
            ans[i*primes[j]]=1;
            if(i%primes[j]==0) break;
        }
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int res=0;
    for(int i=1;i<=n;i++)
    {
    
    
        solve(i);
        res=res^sum[i];
    }
    if(res==0) printf("TT txdy!\n");
    else printf("CC yyds!\n");
    system("pause");
    return 0;
}

F. 学长的白日梦

题目传送门
学长的白日梦

题意见题干

思路:

快速幂+快速乘

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const LL mod=9999999967;
int t;
LL x,y;
LL quick_mul(LL x,LL y)
{
    
    
    LL res=0;
    while(y)
    {
    
    
        if(y&1) res=(res+x)%mod;
        x=(x+x)%mod;
        y=y/2;
    }
    return res;
}
LL quick_pow(LL x,LL y)
{
    
    
    LL res=1;
    while(y)
    {
    
    
        if(y&1) res=quick_mul(res,x)%mod;
        x=quick_mul(x%mod,x%mod)%mod;
        y=y/2;
    }
    return res;
}
int main()
{
    
      
    scanf("%d",&t);
    while(t--)
    {
    
    
        scanf("%llu%llu",&x,&y);
        if(x==1) printf("1\n");
        else
        {
    
    
            LL res=quick_pow(x,y);
            printf("%llu\n",res);
        }
    }
    //system("pause");
    return 0;
}

I.来解方程吧

题目传送门
来解方程吧

题意见题干

思路:

高斯消元法求线性方程组

AC Code

#include<bits/stdc++.h>
using namespace std;
#define maxn 505
#define D double
D a[maxn][maxn];
int n;
int main()
{
    
    
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
    
    
        for(int j=1;j<=n+1;++j)
        {
    
    
            scanf("%lf",&a[i][j]);
        }
    }
    for(int i=1;i<=n;++i)
    {
    
    
        int max=i;
        for(int j=i+1;j<=n;++j)
        {
    
    
            if(fabs(a[j][i])>fabs(a[max][i]))
            {
    
    
                max=j;
            }
        }
        for(int j=1;j<=n+1;++j)//交换
        {
    
    
            swap(a[i][j],a[max][j]);
        }
        for(int j=1;j<=n;++j)
        {
    
    
            if(j!=i)
            {
    
    
                D temp=a[j][i]/a[i][i];
                for(int k=i+1;k<=n+1;++k)
                {
    
    
                    a[j][k]-=a[i][k]*temp;
                    //a[j][k]-=a[j][i]*a[i][k]/a[i][i];
                }
            }
        }
    }
    int flag=0;
    int num=0;
    for(int i=1;i<=n;++i)
    {
    
    
        if(a[i][i]==0&&a[i][n+1]!=0) flag=1;
        else if(a[i][i]!=0) num++;
    }
    if(flag==1) printf("No Solution");
    else if(num!=n) printf("Multiple Solution");
    else
    {
    
    
        for(int i=1;i<=n;++i)
        {
    
    
            printf("%.2lf ",a[i][n+1]/a[i][i]);
        }
    }
    //system("pause");
    return 0;
}

K.dousha的篮球时间

题目传送门
dousha的篮球时间

题意见题干

思路:

考虑删除的数的两边的01情况即可

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,q;
int a[N];
int main()
{
    
    
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
        scanf("%1d",&a[i]);
    int num=0;
    int idx=1;
    while(idx<=n)
    {
    
    
        while(a[idx]==0&&idx<=n)
        {
    
    
            idx++;
            continue;
        }
        int k=0;
        while(a[idx]==1&&idx<=n)
        {
    
    
            idx++;
            k++;
            continue;
        }
        if(k>0) num++;
    }
    printf("%d\n",num);
    int m;
    if(n==1)//如果只有一个元素
    {
    
    
        while(q--)
        {
    
    
            scanf("%d",&m);
            a[1]=a[1]^1;
            printf("%d\n",a[1]);
        }
    }
    else
    {
    
    
        while(q--)
        {
    
    
            int m;//改变的位置
            scanf("%d",&m);
            if(m==1)
            {
    
    
                if(a[m]==0&&a[m+1]==0)
                    num++;
                if(a[m]==1&&a[m+1]==0)
                    num--;
            }
            else if(m==n)
            {
    
    
                if(a[m]==0&&a[m-1]==0) num++;
                if(a[m]==1&&a[m-1]==0) num--;
            }
            else
            {
    
    
                if(a[m]==1)
                {
    
    
                    if(a[m-1]==1&&a[m+1]==1)
                        num++;
                    if(a[m-1]==0&&a[m+1]==0)
                        num--;
                }
                if(a[m]==0)
                {
    
    
                    if(a[m-1]==0&&a[m+1]==0)
                        num++;
                    if(a[m-1]==1&&a[m+1]==1)
                        num--;
                }
            }
            a[m]=a[m]^1;
            printf("%d\n",num);
        }
    }
    //system("pause");
    return 0;
}

L.吃火锅

题目传送门
吃火锅

题意见题干

思路:

可以把每个城市看成一个个的点。可以想到在自己城市吃火锅最便宜的那个点,一定不会跑到其他城市去吃火锅,于是可以从这个点出发,跑最短路。这个问题就转化成了图论的问题,每个点的初始值都是在自己城市吃火锅的成本,然后把这些点都加进优先队列中,跑堆优化的dijkstra即可。

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+10;
int n,m;
int u,v,w;
LL price[N];
int ans[N];
struct Node
{
    
    
    int to;
    int next;
    LL w;
}node[N*2];
int cent=0,head[N];
void add(int u,int v,LL w)
{
    
    
    node[cent].to=v;
    node[cent].w=w;
    node[cent].next=head[u];
    head[u]=cent++;
}
struct tree
{
    
    
    int id;
    LL num;
};
priority_queue<tree>que;
bool operator<(const tree &a,const tree &b)
{
    
    
    return a.num>b.num;
}
void dijkstra()
{
    
    
    while(!que.empty())
    {
    
    
        tree now=que.top();
        que.pop();
        ans[now.id]=0;
        for(int i=head[now.id];~i;i=node[i].next)
        {
    
    
            int to=node[i].to;
            if(price[to]>price[now.id]+2*node[i].w)
            {
    
    
                price[to]=price[now.id]+2*node[i].w;
                if(ans[to]==0)
                {
    
    
                    ans[to]=1;
                    que.push({
    
    to,price[to]});
                }
            }
        }
    }
}
int main()
{
    
    
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
    
    
        scanf("%d%d%lld",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }
    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%lld",&price[i]);
        que.push({
    
    i,price[i]});
        ans[i]=1;
    }
    dijkstra();
    for(int i=1;i<=n;i++)
        printf("%lld ",price[i]);
    //system("pause");
    return 0;
}

M.灾难预警

题目传送门
灾难预警

题意见题干

思路:

bfs+优先队列

AC Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int maze[N][N],n;
int ans[N][N];
struct node
{
    
    
    int x,y;
    int h;
};
priority_queue<node>que;
bool operator<(const node &a,const node &b)
{
    
    
    return a.h<b.h;
}
int dir[4][2]={
    
    {
    
    1,0},{
    
    -1,0},{
    
    0,1},{
    
    0,-1}};
int bfs()
{
    
    
    node start;
    start.x=1,start.y=1,start.h=maze[1][1];
    que.push(start);
    ans[1][1]=1;
    while(!que.empty())
    {
    
    
        node now=que.top();
        que.pop();
        if(now.x==n&&now.y==n) return now.h;
        for(int i=0;i<4;i++)
        {
    
    
            int dx=now.x+dir[i][0],dy=now.y+dir[i][1];
            if(dx<1||dx>n||dy<1||dy>n) continue;
            if(ans[dx][dy]==1) continue;
            node f;
            f.x=dx,f.y=dy,f.h=min(now.h,maze[dx][dy]);
            que.push(f);
            ans[dx][dy]=1;
        }
    }
}
int main()
{
    
    
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&maze[i][j]);
    int res=bfs();
    int q;
    scanf("%d",&q);
    while(q--)
    {
    
    
        int y;
        scanf("%d",&y);
        if(y<=res) printf("Wuhu\n");
        else printf("Hmmm\n");
    }
    //system("pause");
    return 0;
     
}

N.yyds!

题目传送门
yyds

题意见题干

思路:

简单的字符串模拟

AC Code

#include<bits/stdc++.h>
using namespace std;
string str;
int main()
{
    
    
    cin>>str;
    int len=str.length();
    int num1=0,num2=0,num3=0;
    for(int i=0;i<len;i++)
    {
    
    
        if(str[i]=='y')num1++;
        else if(str[i]=='d') num2++;
        else if(str[i]=='s') num3++;
    }
    while(num1>0||num2>0||num3>0)
    {
    
    
        if(num1)
        {
    
    
            printf("y");
            num1--;
        }
        if(num1)
        {
    
    
            printf("y");
            num1--;
        }
        if(num2)
        {
    
    
            printf("d");
            num2--;
        }
        if(num3)
        {
    
    
            printf("s");
            num3--;
        }
    }
    //system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Stevenwuxu/article/details/109268170
今日推荐