CCF認證 2017-12 真題
阿新 • • 發佈:2019-01-09
試題編號: | 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號小朋友獲勝。 給定n |
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公里小明會增加s2的疲勞度。 例如:有5個路口,1號路口到2號路口為小道,2號路口到3號路口為小道,3號路口到4號路口為大道,4號路口到5號路口為小道,相鄰路口之間的距離都是2公里。如果小明從1號路口到5號路口,則總疲勞值為(2+2)2+2+22=16+2+4=22。 現在小芳拿到了地圖,請幫助她規劃一個開車的路線,使得按這個路線開車小明的疲勞度最小。輸入格式 輸入的第一行包含兩個整數n, m,分別表示路口的數量和道路的數量。路口由1至n編號,小明需要開車從1號路口到n號路口。 接下來m行描述道路,每行包含四個整數t, a, b, c,表示一條型別為t,連線a與b兩個路口,長度為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,疲勞度為52=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 ≤ 105,1 ≤ a, b ≤ n,t是0或1,c≤ 105。保證答案不超過106。 |
#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;
}