CCF认证 2017-12 真题

试题编号:201712-1
试题名称:最小差值
时间限制:1.0s
内存限制:256.0MB
问题描述:
问题描述
  给定 n个数,请找出其中相差(差的绝对值)最小的两个数,输出它们的差值的绝对值。
输入格式
  输入第一行包含一个整数 n
  第二行包含 n个正整数,相邻整数之间使用一个空格分隔。
输出格式
  输出一个整数,表示答案。
样例输入
5
1 5 4 8 20
样例输出
1
样例说明
  相差最小的两个数是5和4,它们之间的差值是1。
样例输入
5
9 3 6 1 3
样例输出
0
样例说明
  有两个相同的数3,它们之间的差值是0.
数据规模和约定
  对于所有评测用例,2 ≤  n ≤ 1000,每个给定的整数都是不超过10000的正整数。
#include "stdafx.h"
#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<cmath>  
using namespace std;  
int main()  
{  
	int n;  
	int a[1005];  
	scanf("%d",&n);  
	for(int i=0;i<n;i++)  
		scanf("%d",&a[i]);  
	sort(a,a+n);  
	int ans=100000;  
	for(int i=1;i<n;i++)  
		if(ans>a[i]-a[i-1]) ans=a[i]-a[i-1];  
	printf("%d\n",ans);  
	return 0;  
} 
试题编号:201712-2
试题名称:游戏
时间限制:1.0s
内存限制:256.0MB
问题描述:
问题描述
  有 n个小朋友围成一圈玩游戏,小朋友从1至 n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在 n号小朋友的顺时针方向。
  游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为 k的倍数或其末位数(即数的个位)为 k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
  例如,当n=5, k=2时:
  1号小朋友报数1;
  2号小朋友报数2淘汰;
  3号小朋友报数3;
  4号小朋友报数4淘汰;
  5号小朋友报数5;
  1号小朋友报数6淘汰;
  3号小朋友报数7;
  5号小朋友报数8淘汰;
  3号小朋友获胜。

  给定 nk,请问最后获胜的小朋友编号为多少?
输入格式
  输入一行,包括两个整数 nk,意义如题目所述。
输出格式
  输出一行,包含一个整数,表示获胜的小朋友编号。
样例输入
5 2
样例输出
3
样例输入
7 3
样例输出
4
数据规模和约定
  对于所有评测用例,1 ≤  n ≤ 1000,1 ≤  k ≤ 9。
C++队列Queue类成员函数如下:


back()返回最后一个元素


empty()如果队列空则返回真


front()返回第一个元素


pop()删除第一个元素


push()在末尾加入一个元素


size()返回队列中元素的个数

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<cmath>  
#include<queue>  
using namespace std;  
int main()  
{  
    int n,k;  
    queue<int> q;  
    scanf("%d%d",&n,&k);  
    for(int i=1;i<=n;i++)  
    q.push(i);  
    int t=1,u=1;  
    while(!q.empty())  
    {  
        u=q.front();  
        q.pop();  
        if(t%k==0||t%10==k);  
        else q.push(u);  
        t++;  
    }  
    printf("%d\n",u);  
    return 0;  
}  
试题编号:201712-3
试题名称:Crontab
时间限制:10.0s
内存限制:256.0MB
问题描述:


样例输入
3 201711170032 201711222352
0 7 * * 1,3-5 get_up
30 23 * * Sat,Sun go_to_bed
15 12,18 * * * have_dinner
样例输出
201711170700 get_up
201711171215 have_dinner
201711171815 have_dinner
201711181215 have_dinner
201711181815 have_dinner
201711182330 go_to_bed
201711191215 have_dinner
201711191815 have_dinner
201711192330 go_to_bed
201711200700 get_up
201711201215 have_dinner
201711201815 have_dinner
201711211215 have_dinner
201711211815 have_dinner
201711220700 get_up
201711221215 have_dinner
201711221815 have_dinner


#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<cmath>  
#include<vector>  
#include<cstdlib>  
#include<queue>  
using namespace std;  
const int N=20+1;  
const string Month[]={"nothing","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};  
const string Week[]={"sun","mon","tue","wed","thu","fri","sat"};  
const int dnum[]={0,31,28,31,30,31,30,31,31,30,31,30,31};  
struct qj //区间,代表从a到b这个时间段  (-1,-1)代表任何时间都可以   
{  
    int a;   
    int b;  
};  
struct node //这里保存符合要求的时间区间   
{  
    vector<qj> mte;  
    vector<qj> hour;  
    vector<qj> day;  
    vector<qj> mon;  
    vector<qj> week;  
    string cmd;  
}m[N];  
struct cmder //命令和操作的时间   
{  
    int year,month,day,hour,mte;  
    string cmd;  
    cmder(int a,int b,int c,int d,int e,string f)  
    {  
        year=a;month=b;day=c;hour=d;mte=e;  
        cmd=f;  
    }  
    bool operator < (const cmder &u) const //要按时间和先后顺序排好   
    {  
        if(year>u.year) return true;  
        if(year<u.year) return false;  
        if(month>u.month) return true;  
        if(month<u.month) return false;  
        if(day>u.day) return true;  
        if(day<u.day) return false;  
        if(hour>u.hour) return true;  
        if(hour<u.hour) return false;  
        if(mte>u.mte) return true;  
        if(mte<u.mte) return false;  
        return true; //先入靠前   
    }  
};  
priority_queue<cmder> outq; //把时间范围内需要操作的命令放进来排好序   
bool is_end(int year,int month,int day,int hour,int mte,int uyear,int umonth,int uday,int uhour,int umte) //判断是否超出时间范围   
{  
    if(year>uyear) return true;  
    if(year<uyear) return false;  
    if(month>umonth) return true;  
    if(month<umonth) return false;  
    if(day>uday) return true;  
    if(day<uday) return false;  
    if(hour>uhour) return true;  
    if(hour<uhour) return false;  
    if(mte>umte) return true;  
    if(mte<umte) return false;  
    return true;   
}  
bool is_week(int q,int e) //判断周是否符合   
{  
    bool flag=false;  
    int l=m[q].week.size();  
    for(int i=0;i<l;i++)  
    if(m[q].week[i].b==-1||e<=m[q].week[i].b&&e>=m[q].week[i].a)  
    {  
        flag=true;  
        break;  
    }  
    return flag;  
}  
bool is_month(int q,int d) //判断月是否符合   
{  
    bool flag=false;  
    int l=m[q].mon.size();  
    for(int i=0;i<l;i++)  
    if(m[q].mon[i].b==-1||d<=m[q].mon[i].b&&d>=m[q].mon[i].a)  
    {  
        flag=true;  
        break;  
    }  
    return flag;  
}  
bool is_day(int q,int c) //判断天是否符合   
{  
    bool flag=false;  
    int l=m[q].day.size();  
    for(int i=0;i<l;i++)  
    if(m[q].day[i].b==-1||c<=m[q].day[i].b&&c>=m[q].day[i].a)  
    {  
        flag=true;  
        break;  
    }  
    return flag;  
}  
bool is_hour(int q,int nb) //判断小时是否符合   
{  
    bool flag=false;  
    int l=m[q].hour.size();  
    for(int i=0;i<l;i++)  
    if(m[q].hour[i].b==-1||(nb<=m[q].hour[i].b)&&(nb>=m[q].hour[i].a))  
    {  
        flag=true;  
        break;  
    }  
    return flag;  
}  
bool is_mte(int q,int a) //判断分钟是否符合   
{  
    bool flag=false;  
    int l=m[q].mte.size();  
    for(int i=0;i<l;i++)  
    if(m[q].mte[i].b==-1||a<=m[q].mte[i].b&&a>=m[q].mte[i].a)  
    {  
        flag=true;  
        break;  
    }  
    return flag;  
}  
int isyear(int a) //判断闰年   
{  
    if(a%400==0||a%4==0&&a%100!=0) return 1;  
    return 0;  
}  
int zeller(int year,int month,int day) //蔡勒公式,计算这天是周几,公式只适合于1582年10月15日之后的情形  
{  
    int m,d=day;  
    if(month<3)  
    {  
        m=month+12;  
        year--;  
    }  
    else m=month;  
    int c=year/100;   
    int y=year%100;  
    int w=(c/4)-2*c+(y+y/4)+(13*(m+1)/5)+day-1;  
    return (w%7+7)%7;  //返回0代表周日   
}  
int n;  
string s,t;  
int main()  
{  
    cin>>n>>s>>t;  
    int sa,sb,sc,sd,se;  
    int ea,eb,ec,ed,ee;  
    sa=sb=sc=sd=se=0;  
    ea=eb=ec=ed=ee=0;  
    for(int i=0;i<4;i++) //计算开始时间   
    sa=sa*10+s[i]-'0';  
    for(int i=4;i<6;i++)  
    sb=sb*10+s[i]-'0';  
    for(int i=6;i<8;i++)  
    sc=sc*10+s[i]-'0';  
    for(int i=8;i<10;i++)  
    sd=sd*10+s[i]-'0';  
    for(int i=10;i<12;i++)  
    se=se*10+s[i]-'0';  
    for(int i=0;i<4;i++) //计算结束时间   
    ea=ea*10+t[i]-'0';  
    for(int i=4;i<6;i++)  
    eb=eb*10+t[i]-'0';  
    for(int i=6;i<8;i++)  
    ec=ec*10+t[i]-'0';  
    for(int i=8;i<10;i++)  
    ed=ed*10+t[i]-'0';  
    for(int i=10;i<12;i++)  
    ee=ee*10+t[i]-'0';  
    for(int q=0;q<n;q++)  
    {  
        string a;  
        int l;  
        qj k;  
        cin>>a;  
        l=a.length();  
        int t=0,t0;  
        bool flag=false;  
        for(int i=0;i<l;i++) //处理分钟   
        {  
            if(isdigit(a[i])) t=t*10+a[i]-'0';  
            else if(a[i]=='-')  
            {  
                t0=t;  
                t=0;  
                flag=true;  
            }  
            else if(a[i]==',')  
            {  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                m[q].mte.push_back(k);  
                t=0;  
                flag=false;  
            }  
            else if(a[i]=='*')  
            {  
                k.a=k.b=-1;  
                m[q].mte.push_back(k);  
                break;  
            }  
            if(i==l-1)   
            {  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                m[q].mte.push_back(k);  
                t=0;  
            }  
        }  
        cin>>a;  
        l=a.length();  
        t=0;  
        flag=false;  
        for(int i=0;i<l;i++) //处理小时   
        {  
            if(isdigit(a[i])) t=t*10+a[i]-'0';  
            else if(a[i]=='-')  
            {  
                t0=t;  
                t=0;  
                flag=true;  
            }  
            else if(a[i]==',')  
            {  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                m[q].hour.push_back(k);  
                t=0;  
                flag=false;  
            }  
            else if(a[i]=='*')  
            {  
                k.a=k.b=-1;  
                m[q].hour.push_back(k);break;  
            }  
            if(i==l-1)  
            {  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                m[q].hour.push_back(k);  
                t=0;  
            }  
        }  
        cin>>a;  
        l=a.length();  
        t=0;  
        flag=false;  
        for(int i=0;i<l;i++) //处理天   
        {  
            if(isdigit(a[i])) t=t*10+a[i]-'0';  
            else if(a[i]=='-')  
            {  
                t0=t;  
                t=0;  
                flag=true;  
            }  
            else if(a[i]==',')  
            {  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                m[q].day.push_back(k);  
                t=0;  
                flag=false;  
            }  
            else if(a[i]=='*')  
            {  
                k.a=k.b=-1;  
                m[q].day.push_back(k);break;  
            }  
            if(i==l-1)  
            {  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                m[q].day.push_back(k);  
                t=0;  
                flag=false;  
            }  
        }  
        string a0="";  
        cin>>a;  
        l=a.length();  
        t=0;  
        flag=false;  
        for(int i=0;i<l;i++) //处理月   
        {  
            if(isdigit(a[i])) t=t*10+a[i]-'0';  
            else if(isalpha(a[i])) a0+=a[i];  
            else if(a[i]=='-')  
            {  
                if(a0.length()!=0)  
                {  
                    for(int j=0;j<a0.length();j++)  
                    a0[j]=tolower(a0[j]);  
                    for(int j=0;j<13;j++)  
                    if(Month[j]==a0)  
                    {  
                        t=j;  
                        break;  
                    }  
                }  
                a0="";  
                t0=t;  
                t=0;  
                flag=true;  
            }  
            else if(a[i]==',')  
            {  
                if(a0.length()!=0)  
                {  
                    for(int j=0;j<a0.length();j++)  
                    a0[j]=tolower(a0[j]);  
                    for(int j=0;j<13;j++)  
                    if(Month[j]==a0)  
                    {  
                        t=j;  
                        break;  
                    }  
                }  
                a0="";  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                t=0;  
                m[q].mon.push_back(k);  
                flag=false;  
            }  
            else if(a[i]=='*')  
            {  
                k.a=k.b=-1;  
                m[q].mon.push_back(k);break;  
            }  
            if(i==l-1)  
            {  
                if(a0.length()!=0)  
                {  
                    for(int j=0;j<a0.length();j++)  
                    a0[j]=tolower(a0[j]);  
                    for(int j=0;j<13;j++)  
                    if(Month[j]==a0)  
                    {  
                        t=j;  
                        break;  
                    }  
                }  
                a0="";  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                t=0;  
                m[q].mon.push_back(k);  
                flag=false;  
            }  
        }  
        a0="";  
        cin>>a;  
        l=a.length();  
        t=0;  
        flag=false;  
        for(int i=0;i<l;i++) //处理周   
        {  
            if(isdigit(a[i])) t=t*10+a[i]-'0';  
            else if(isalpha(a[i])) a0+=a[i];  
            else if(a[i]=='-')  
            {  
                if(a0.length()!=0)  
                {  
                    for(int j=0;j<a0.length();j++)  
                    a0[j]=tolower(a0[j]);  
                    for(int j=0;j<7;j++)  
                    if(Week[j]==a0)  
                    {  
                        t=j;  
                        break;  
                    }  
                }  
                a0="";  
                t0=t;  
                t=0;  
                flag=true;  
            }  
            else if(a[i]==',')  
            {  
                if(a0.length()!=0)  
                {  
                    for(int j=0;j<a0.length();j++)  
                    a0[j]=tolower(a0[j]);  
                    for(int j=0;j<7;j++)  
                    if(Week[j]==a0)  
                    {  
                        t=j;  
                        break;  
                    }  
                }  
                a0="";  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                t=0;  
                m[q].week.push_back(k);  
                flag=false;  
            }  
            else if(a[i]=='*')  
            {  
                k.a=k.b=-1;  
                m[q].week.push_back(k);break;  
            }  
            if(i==l-1)  
            {  
                if(a0.length()!=0)  
                {  
                    for(int j=0;j<a0.length();j++)  
                    a0[j]=tolower(a0[j]);  
                    for(int j=0;j<7;j++)  
                    if(Week[j]==a0)  
                    {  
                        t=j;  
                        break;  
                    }  
                }  
                a0="";  
                if(flag) k.a=t0;  
                else k.a=t;  
                k.b=t;  
                t=0;  
                m[q].week.push_back(k);  
                flag=false;  
            }  
        }  
        cin>>a;  
        m[q].cmd=a;  
        int i=sa,j=sb,nk=sc,x=sd,y=se; //这里从头到尾过一遍时间,加了回溯   
        for(;i<=ea;i++,j=1)  
        for(;j<=12;j++,nk=1)  
        if(is_month(q,j))  
        for(;nk<=dnum[j]+(j==2?isyear(i):0);nk++,x=0)  
        if(is_day(q,nk)&&is_week(q,zeller(i,j,nk)))  
        for(;x<24;x++,y=0)  
        if(is_hour(q,x))  
        for(;y<60;y++)  
        {  
            if(is_end(i,j,nk,x,y,ea,eb,ec,ed,ee)) goto stop; //超出时间跳出循环   
            if(is_mte(q,y)) outq.push(cmder(i,j,nk,x,y,a)); //符合的话就加入队列   
        }  
        stop:;  
    }  
    while(!outq.empty()) //按顺序输出   
    {  
        cmder out=outq.top();  
        outq.pop();  
        printf("%04d%02d%02d%02d%02d ",out.year,out.month,out.day,out.hour,out.mte),cout<<out.cmd<<endl;  
    }  
    return 0;  
}  
问题描述
试题编号:201712-4
试题名称:行车路线
时间限制:1.0s
内存限制:256.0MB
问题描述:
问题描述
  小明和小芳出去乡村玩,小明负责开车,小芳来导航。
  小芳将可能的道路分为大道和小道。大道比较好走,每走1公里小明会增加1的疲劳度。小道不好走,如果连续走小道,小明的疲劳值会快速增加,连续走 s公里小明会增加 s 2的疲劳度。
  例如:有5个路口,1号路口到2号路口为小道,2号路口到3号路口为小道,3号路口到4号路口为大道,4号路口到5号路口为小道,相邻路口之间的距离都是2公里。如果小明从1号路口到5号路口,则总疲劳值为(2+2) 2+2+2 2=16+2+4=22。
  现在小芳拿到了地图,请帮助她规划一个开车的路线,使得按这个路线开车小明的疲劳度最小。
输入格式
  输入的第一行包含两个整数 nm,分别表示路口的数量和道路的数量。路口由1至 n编号,小明需要开车从1号路口到 n号路口。
  接下来 m行描述道路,每行包含四个整数 tabc,表示一条类型为 t,连接 ab两个路口,长度为 c公里的双向道路。其中 t为0表示大道, t为1表示小道。保证1号路口和 n号路口是连通的。
输出格式
  输出一个整数,表示最优路线下小明的疲劳度。
样例输入
6 7
1 1 2 3
1 2 3 2
0 1 3 30
0 3 4 20
0 4 5 30
1 3 5 6
1 5 6 1
样例输出
76
样例说明
  从1走小道到2,再走小道到3,疲劳度为5 2=25;然后从3走大道经过4到达5,疲劳度为20+30=50;最后从5走小道到6,疲劳度为1。总共为76。
数据规模和约定
  对于30%的评测用例,1 ≤  n ≤ 8,1 ≤  m ≤ 10;
  对于另外20%的评测用例,不存在小道;
  对于另外20%的评测用例,所有的小道不相交;
  对于所有评测用例,1 ≤  n ≤ 500,1 ≤  m ≤ 10 5,1 ≤  ab ≤  nt是0或1, c  ≤ 10 5。保证答案不超过10 6


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=500+10;
const ll inf=1e18; //需要开long long,虽然结果不大于1e6,但中间值依然可能爆int,就因为这个80分,天真了 
bool vis[N];
int que[N];
ll dist[N],dist0[N]; //前驱为大路和前驱为小路分别计算距离 
ll g[N][N],g0[N][N]; //大路邻接矩阵和小路邻接矩阵 
void SPFA(int start,int n)
{
    int front=0,rear=0;
    for(int v=1;v<=n;v++)
    {
        if(v==start)
        {
            que[rear++]=v;
            vis[v]=true;
            dist[v]=dist0[v]=0;
        }
        else
        {
            vis[v]=false;
            dist[v]=dist0[v]=inf;
        }
    }
    while(front!=rear)
    {
        int u=que[front++];
        vis[u]=false;
        if(front>=N)front=0; 
        for(int i=1;i<=n;i++)
        {
            ll v=g[u][i];
            if(dist[i]>dist[u]+v) //走大路 
            {
                dist[i]=dist[u]+v;
                if(!vis[i])
                {
                    vis[i]=true;
                    que[rear++]=i; 
                    if(rear>=N)rear=0;
                }
            }
            if(dist[i]>dist0[u]+v) //走大路 
            {
                dist[i]=dist0[u]+v;
                if(!vis[i])
                {
                    vis[i]=true;
                    que[rear++]=i; 
                    if(rear>=N)rear=0;
                }
            }
			if(g0[u][i]!=inf) //如果小路能到达 
			{
				v=g0[u][i]*g0[u][i];
				if(dist0[i]>dist[u]+v) //走小路 ,前驱为小路时不能走小路 
            	{
               		dist0[i]=dist[u]+v;
               	 	if(!vis[i])
                	{
                  	 	vis[i]=true;
                  		que[rear++]=i; 
                   	 	if(rear>=N)rear=0;
               	 	}
           	 	}
			}
        }
    }
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	ll t,a,b,c;
	for(int i=0;i<=n;i++)
	for(int j=0;j<=n;j++)
	g[i][j]=g0[i][j]=inf;
	for(int i=0;i<m;i++)
	{
		scanf("%lld%lld%lld%lld",&t,&a,&b,&c);
		if(t&&g0[a][b]>c) g0[a][b]=g0[b][a]=c;
		if(!t&&g[a][b]>c) g[a][b]=g[b][a]=c;
	}
	for(int i=1;i<=n;i++) //这里用floyd事先计算好只走小路时两两点之间的最短距离
	for(int j=i+1;j<=n;j++)
	{
		for(int k=1;k<=n;k++)
		{
			if(k==i||k==j) continue;
			if(g0[i][j]>g0[i][k]+g0[k][j]) g0[i][j]=g0[j][i]=g0[i][k]+g0[k][j];
		}
	}
	SPFA(1,n); //spfa 
	printf("%lld\n",min(dist[n],dist0[n]));
	return 0;
} 
问题描述
试题编号:201712-5
试题名称:商路
时间限制:5.0s
内存限制:512.0MB
问题描述:






样例输入
1
12
0 0 10 30
1 10 10 11
1 100 10 10
2 20 10 7
2 5 10 9
4 8 5 1
5 5 5 4
7 5 1 1
3 1 200 1
6 3 22 22
9 10 99 0
11 10 6 8
样例输出
224
样例输入
10
10
0 0 981021 2878
1 2982 103544 16423
2 9309 1146606 60
1 9632 339699 4022
1 4859 1050430 27644
4 7152 1016794 8381
2 691 202924 1579
5 682 312623 1947
1 5622 434383 1966
1 1036 337962 4867
10
0 0 613160 4178
1 6039 530965 36077
1 2641 588435 10697
2 8015 1773940 21360
2 9456 1536141 20760
3 1540 1069223 6060
3 4132 1802960 9712
4 1295 338084 630
4 5977 858393 3942
5 1981 1569807 8875
10
0 0 3297948 29281
1 2838 4499071 56444
2 1723 5082712 58167
3 6932 1899951 86996
4 6111 4673596 39622
5 4854 1283153 52866
6 1600 3076850 58518
7 2887 3936856 44586
8 9662 1653482 1115
9 6359 1438146 7533
10
0 0 3827584 9067
1 1114 1938309 90351
2 1913 3135879 31961
3 210 3118784 55465
4 6982 1115456 4482
5 4326 2504229 8147
6 3567 1296569 21072
6 857 3723988 867
7 2726 1349738 682
6 2569 1465079 9994
10
0 0 4152770 20839
1 3728 1993622 104795
2 3358 1563274 31216
3 6794 2231093 43445
4 2197 2316621 7602
5 1174 2985157 7136
6 8333 103275 6346
6 5129 3083322 3511
7 469 2368248 9692
7 5732 3765843 8563
10
0 0 3091416 127451
1 2323 3358598 10828
2 8139 3723827 15116
3 9725 2486973 25964
4 1954 2821451 18368
5 8257 3938729 32443
6 2554 4006939 13576
6 5881 511102 9605
7 7999 1954660 1148
7 3260 1916815 8710
10
0 0 366406 31967
1 7426 2566312 2237
1 654 2294113 5913
2 8186 893528 10662
2 6453 1512505 13321
4 6429 616635 6615
6 5842 2578315 14449
5 3568 2988564 9781
6 1704 1044306 9036
7 4747 155934 4217
10
0 0 2481887 67676
1 2514 2068792 41590
2 5134 2460668 181
1 608 1693903 5729
2 2202 2804903 37359
5 611 1673964 6522
6 429 1245126 10648
6 7898 358662 6483
7 4194 1315545 8960
6 1193 224838 7332
10
0 0 3403835 116677
1 77 2005502 44152
2 2913 3325129 47250
2 8094 2319341 37
3 3750 458636 52717
5 8465 1635392 21518
6 9440 1757959 2079
6 8555 2306608 4397
6 5530 2658501 440
7 1594 1833614 690
10
0 0 1477756 44072
1 8380 3425538 18191
2 7951 978970 6357
1 2602 184752 6671
3 725 2947560 1525
5 1314 3589295 39573
6 1755 1675874 6532
6 8848 2470638 3789
7 1620 2129738 9070
7 9509 2363613 6569
样例输出
970205
613151
0
4682720
3959657
2626087
19106
0
1522734
5999689
答题栏
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const ll MOD=1e18;
const int N=1e5+10;
ll v[N],f[N],u[N],s[N];
ll ans[N];
int vis[N];
void init()
{
	memset(ans,0,sizeof(ans));
	memset(vis,0,sizeof(vis));
}
int main()
{
	int T,n;
	scanf("%d",&T);
	while(T--)
	{
		init(); //初始化 
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d%d%d",&u[i],&s[i],&v[i],&f[i]);
			vis[u[i]]++; //vis数组保存这个点的直接下级数量 
		}
		int q[N],q0=0,q1=0;
		for(int i=1;i<=n;i++) //这里类似拓扑排序,直接下级数量为零入队 
		if(!vis[i]) q[q1++]=i;
		while(q0<q1)
		{
			int k=q[q0++];
			int t=u[k],d=s[k];
			vis[t]--;
			if(!vis[t]) q[q1++]=t; //直接下级全都处理过了,入队 
			while(t) //寻找所有上级,计算上级城市到这里的获利,取最大值 
			{
				ans[t]=max(ans[t],(ans[k]+v[t]-(f[t]-d)*(f[t]-d))); //ans里保存了以这个城市为开头的商路最大价值 
				d+=s[t];
				t=u[t];
			}
		}
		ll sum=0;
		for(int i=1;i<=n;i++) sum=(sum+ans[i])%MOD; //计算总价值 
		printf("%lld\n",sum);
	}
	return 0;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值