1.P8509 如何得到 npy

题意:

给定一棵n个节点的树,n-1条边,和关键点,s,t,求其他所有点到s或t的最短距离和,并标记每条边的方向,为1或0或2

思路:

从s和t分别dfs1搜寻,求出每个点到s或t的最短距离,并标记是到s还是t; 从s和t分别dfs2标搜寻,求出最短距离和以及边方向

代码:

using namespace std;
#define ll long long
#define M 300005
int n,s,t,w[M],v[M];//w是到s是源点,还是t是源点,v是边是1或2或0
int idx,h[M],vet[2*M],len[M*2],nxt[M*2];
ll d[M],ans;
void add(int a ,int b ,int c){
    nxt[++idx]=h[a],vet[idx]=b,len[idx]=c;
    h[a]=idx;
}
void dfs1(int x,int pre,int tp){
    for (int i = h[x]; i ; i=nxt[i]) {
        int y=vet[i],z=len[i];
        if(y==pre)continue;
        if(d[y]>d[x]+z){
            d[y]=d[x]+z;
            w[y]=tp;
            dfs1(y,x,tp);
        }
    }
}
void dfs2(int x,int pre,int tp){
    for (int i = h[x]; i ; i=nxt[i]) {
        int y=vet[i];
        if(y==pre)continue;
        if(w[y]==tp){
            ans+=d[y];
            if(i&1)
                v[i/2]=1;
            else
                v[i/2]=2;
            dfs2(y,x,tp);
        }
    }
}

int main(){
    cin>>n>>s>>t;
    idx=1;
    for (int i = 1; i <=n-1 ; ++i) {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
    }
    for (int i = 1; i <=n ; ++i) {
        d[i]=1e16;
    }
    d[s]=0;
    dfs1(s,0,s);
    d[t]=0;
    w[t]=0;
    dfs1(t,0,t);
    dfs2(s,0,s);
    dfs2(t,0,t);
    cout<<ans<<'\n';
    for (int i = 1; i <=n-1 ; ++i) {
        cout<<v[i];
    }
}

2.P8508 做不完的作业


题意:

共有n个任务,一天有x时间,前i天睡觉时间不能小于rxi,r=p/q,求最少多少天可以完成任务(每天都必须睡觉)

思路:

一天时间 − 将要完成的作业时间 + 当前总睡觉时间 + l 天整天睡觉的总时长 ≥ 当前天的 l 天后的要求总睡觉时长

代码:

#include<bits/stdc++.h>
using namespace std;
long long n,x,p,q,i=1,sum,t,w;
int main(){
    cin>>n>>x>>p>>q;
    while(n--){
        cin>>w;
        if((x-t-w+sum)*q>=i*p*x&&x-t>w)t+=w;
        else{
            sum+=x-t;
            i++;
            long long l=ceil((q*(sum+x-w)-p*i*x)*1.0/(x*p-x*q));
            if(l>0){
                sum+=x*l;
                i+=l;
            }
            t=w;
        }
    }
    cout<<i;
}

P1148 拱猪计分

题意:求分数

思路:注释中

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct card
{
    char type;//牌的种类
    int point;//牌的点数
}c[100];
int ans[100];
int main()
{
    int time=0,num,t=0,sco=0,hflag=0,sflag=0,dflag=0;//time用来统计总的牌数,t用来特判换行,sco用来储存分数,其他的几个用来检查有无特殊情况。
    while(cin>>num)
    {
        time++;
        for(int i=1;i<=num;i++)
            cin>>c[i].type>>c[i].point;
        for(int i=1;i<=num;i++)
            if(c[i].type=='H') t++;
        if(t==13) hflag=1;//即所有红心在一家
        for(int i=1;i<=num;i++)
            if(c[i].type=='S'&&c[i].point==12) sflag=1;//出现S12
        for(int i=1;i<=num;i++)
            if(c[i].type=='D'&&c[i].point==11) dflag=1;//出现D11
        for(int i=1;i<=num;i++)
        {
            if(c[i].type=='C'&&c[i].point==10)
                swap(c[i],c[num]);//把C10换到最后
            if(hflag==1)//所有红心在一家的情况
            {
                if(sflag==1&&dflag==1) sco=500;
                else
                {
                    sco=200;
                    if(sflag==1) sco-=100;
                    if(c[i].type=='D'&&c[i].point==11) sco+=100;
                }
            }
            else
            {
                if(c[i].type=='H')
                {
                    if(c[i].point==1) sco-=50;
                    if(c[i].point==2) sco-=2;
                    if(c[i].point==3) sco-=3;
                    if(c[i].point==4) sco-=4;
                    if(c[i].point==5) sco-=5;
                    if(c[i].point==6) sco-=6;
                    if(c[i].point==7) sco-=7;
                    if(c[i].point==8) sco-=8;
                    if(c[i].point==9) sco-=9;
                    if(c[i].point==10) sco-=10;
                    if(c[i].point==11) sco-=20;
                    if(c[i].point==12) sco-=30;
                    if(c[i].point==13) sco-=40;
                }
                if(c[i].type=='S'&&c[i].point==12) sco-=100;
                if(c[i].type=='D'&&c[i].point==11) sco+=100;
            }
            if(c[i].type=='C'&&c[i].point==10)
            {
                if(num==1) sco=50;//如果仅有这一张牌
                else sco*=2;
            }
        }
        ans[time]=sco;//把答案存进数组
        t=0,sco=0,hflag=0,sflag=0,dflag=0;//变量全部重置
        memset(c,0,sizeof(c));//清空储存牌的数组
    }
    for(int i=1;i<=time;i++)
    {
        if(i%4==1&&ans[i]==0&&ans[i+1]==0&&ans[i+2]==0&&ans[i+3]==0)//判断结束条件
            break;
        if(ans[i]>0) cout<<"+"<<ans[i]<<" ";//正数要加'+'
        else cout<<ans[i]<<" ";//负数和0直接输出
        if(i%4==0) cout<<endl;//每四张牌换行
    }
    return 0;
}

posted on 2023-01-08 14:30  IR101  阅读(12)  评论(0编辑  收藏  举报  来源