题目名称 | 存款 | 旅行安排 | 花篮 | 夜晚 |
可执行文件名 | Save | Plan | Baskets | Night |
输入文件名 | Save.in | Plan.in | Baskets.in | Night.in |
输出文件名 | Save.out | Plan.out | Baskets.out | Night.out |
每个测试点时限 | 1s | 1s | 1s | 1s |
内存限制 | 64M | 64M | 64M | 64M |
测试点数目 | 10 | 10 | 10 | 10 |
每个测试点分值 | 10 | 10 | 10 | 10 |
题目类型 | 传统型 | 传统型 | 传统型 | 传统型 |
1、 文件名(程序名和输入输出文件名)对大小写无区分(Windows平台测试)。
2、 C/C++中函数main() 的返回值类型必须是int,程序正常结束时的返回值必须是0。
3、 统一评测平台为win7,内存2GB
4、 比赛期间请独立思考,完成问题
5、 比赛时间为3个小时,请选手把握好时间,认真检查,考出自己满意的成绩
Loongint的存款
【Description】
Loongint希望你能帮他规划一下今年一年的收入和支出。对于每一个月,Loongint可以选择打工挣钱或者陪MM去消费,每个月挣的钱(s)和消费的钱(d)的数额都是一定的。可是,Loongint的MM不希望Loongint有结余,因为这样Loongint可能去找别的MM。可是作为一个顶天立地的男人J,Loongint非常渴望能结余。
MM只能查Loongint任意连续五个月的经济情况,所以Loongint必须让任意连续五个月的收入都是负的(也就是五个月的总支出大于总收入)。求年终Loongint能结余么?如果能,输出最大结余,如果不能,输出No Save。
【Input】
第一行n表示有n组测试数据。
接下来n行,每行有s和d。
【Output】
n行,每行输出一年的最大结余或者No Save
【Sample Input】
2
1 1
14 6
【Sample Output】
0
No Save
【Hint】
对于30%的数据,1=<n<=100
对于100%的数据,1<=n<=100000;s,d和最后的解都属于Longint。
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int n; int s,d; int solve(int s, int d){ if (4*s-d<0) return 10*s-2*d; if (3*s-2*d<0) return 8*s-4*d; if (2*s-3*d<0) return 6*s-6*d; if (s-4*d<0) return 3*s-9*d; return -1; } int main(){ freopen("save.in","r",stdin); freopen("save.out","w",stdout); scanf("%d\n",&n); for (int i=1;i<=n;i++){ scanf("%d%d",&s,&d); int t=solve(s,d); if (t<0) printf("No Save\n"); else printf("%d\n",t); } return 0; }
Loongint的旅行安排
【Description】
Loongint和MM要出去旅行,出行前规划旅行方案时,MM给Loongint出了一个难题。她说,在她心中,不同的地方能给她不同的感受,而感受可以用喜爱值Li表示出来,她希望这次旅行能正好得到W的喜爱值。为了考验Loongint是否爱他,她只是给了Loongint所有的Li和W值,却并不告诉Loongint哪个是哪个…Loongint手头比较紧,只能支付去三个地方的费用,所以Loongint必须从这些数中找出三个Li和一个W,并且使W尽量的大。
Loongint一心想和MM去旅行,哪里有时间想这个问题,所以,交给了Hzoi同仁的你…
【Input】
输入数据有两组(为了防止No Solution骗分J)。
对于每一组,第一行n表示有n个数值,接下来n行为每个数值的大小。
【Output】
两组输出。分别为每组的答案。如果可以找出三个Li和一个W,那么就输出最大的W,如果不能,就输出No Solution。
【Sample Input】
4
5
5
5
5
4
1
2
3
6
【Sample Output】
No Solution
6
【Hint】
对于30%的数据,1=<n<=100
对于100%的数据,1<=n<=1000,Li和W都属于[-536870911,536870911]
#include <cstdio> #include <cstring> #include <algorithm> #define INF 210000000 using namespace std; int n; int ans; int a[1010]; struct node{ int x,a,b; }q[1000000]; int tot; int cmp(const node &a,const node &b){return a.x<b.x;} bool find(int x,int a,int b){ int l=0,r=tot; while (l<r){ int mid=(l + r) >> 1; if (q[mid].x<x) l=mid+1;else r=mid; } while (l<tot && q[l].x==x){ if (q[l].a==a || q[l].b==a || q[l].a==b || q[l].b==b) l++;else break; } if (q[l].x!=x) return false; return true; } int main(){ freopen("plan.in","r",stdin); freopen("plan.out","w",stdout); while (scanf("%d",&n)!=EOF){ if (n==0) break; for (int i=1;i<=n;i++){ scanf("%d",&a[i]); } ans=-INF; tot=0; memset(q,0,sizeof(q)); for (int i=1;i<n;i++){ for (int j=i+1;j<=n;j++){ q[tot].x=a[i]+a[j]; q[tot].a=i; q[tot++].b=j; } } sort(q,q+tot,cmp); for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ if (i!=j){ int t=a[i]-a[j]; if (find(t,i,j)){ if (a[i]>ans) ans=a[i]; } } } } if (ans==-INF) printf("No Solution\n");else printf("%d\n",ans); } return 0; }
Loongint的花篮
【Description】
Loongint要和MM结婚了。在两人的走进礼堂的红地毯两侧,需要摆一些装饰用的花篮,有一些不同高度的花篮,现在这些花篮被Loongint依照自己的美学观念编号为S1,S2,S3…Sn(两侧的花篮高度一样)。可Loongint的MM对这些花篮的摆放方式有不同的看法,她觉得满足以下条件的花篮摆放才是最好的。
如果对于区间[Si,Sj](1<=i<j<=n)中任意的花篮都比Si高且比Sj低,那么这个区间称为一个美学区间。对于所有的美学区间,其长度(定义为j-i)都必须小于等于k,如果有长度大于k的美学区间,MM就会不高兴,Loongint就会有麻烦…
【Input】
第一行为m。表示有m组测试数据。
对于每一组:
第一行n,k,分别表示花篮的数量和美学区间的最大长度。
第二行为n个数,分别表示S1,S2,S3…Sn的值。
【Output】
如果根本不存在美学区间,输出-1。
如果存在美学区间,那么如果任意区间的长度都小于等于k,那么输出最大的长度,否则输出最大长度比k大多少(MaxLength-k)。
【Sample Input】
3
4 2
5 4 3 6
4 1
6 5 4 3
4 2
1 2 3 4
【Sample Output】
1
-1
1
【Hint】
对于30%的测试数据,1<=n<=100。
对于60%的测试数据,1=<n<=5555。
对于100%的测试数据,1<=n<=100000,0<Si<=100000,1=<m<=3。
#include <cstdio> #include<cmath> #include <cstring> #define INF 2000000000 int T; int n,k; int a[110000]; //int g[110000][30]; int f[110000][30]; //int gid[110000][30]; int fid[110000][30]; int q[110000]; int len[110000]; int top; int maxlen; int min(int a,int b){return a<b?a:b;} int max(int a,int b){return a>b?a:b;} /* void search(int l,int r){ if (l==r) return; int t=(int)(log10((double)(r-l+1))/log10(2.0)); int mi,ma; if (g[l][t]<g[r-(1 << t)+1][t]) mi=gid[l][t];else mi=gid[r-(1 << t)+1][t]; if (f[l][t]>f[r-(1 << t)+1][t]) ma=fid[l][t];else ma=fid[r-(1 << t)+1][t]; if (mi<ma){ if (ma-mi>maxlen) maxlen=ma-mi; if (mi-1>l) search(l,mi-1); if (ma+1<r) search(ma+1,r); }else if (mi>ma){ if (ma>l) search(l,ma); if (mi<r) search(mi,r); if (mi-1>ma+1) search(ma+1,mi-1); } } */ int main(){ freopen("baskets.in","r",stdin); freopen("baskets.out","w",stdout); scanf("%d",&T); while (T--){ scanf("%d%d",&n,&k); memset(a,0,sizeof(a)); // memset(g,0,sizeof(g)); memset(f,0,sizeof(f)); // memset(gid,0,sizeof(gid)); memset(fid,0,sizeof(fid)); memset(q,0,sizeof(q)); maxlen=0; top=0; memset(len,0,sizeof(len)); for (int i=1;i<=n;i++){ scanf("%d",&a[i]); // g[i][0]=a[i]; // gid[i][0]=i; f[i][0]=a[i]; fid[i][0]=i; } for (int i=1;i<=n+1;i++){ while (a[q[top]]>=a[i] && top>0){ len[q[top]]=i-1; top--; } q[++top]=i; } for (int j=1;j<=(int)(log10((double)n)/log10(2.0));j++) for (int i=1;i<=(n-(1 << j)+1);i++){ /* g[i][j]=g[i+(1 << (j-1))][j-1]; gid[i][j]=gid[i+(1 << (j-1))][j-1]; if (g[i][j-1]<g[i][j]){ g[i][j]=g[i][j-1]; gid[i][j]=gid[i][j-1]; } g[i][j]=g[i][j-1]; gid[i][j]=gid[i][j-1]; if (g[i+(1 << (j-1))][j-1]<g[i][j]){ g[i][j]=g[i+(1 << (j-1))][j-1]; gid[i][j]=gid[i+(1 << (j-1))][j-1]; } */ f[i][j]=f[i][j-1]; fid[i][j]=fid[i][j-1]; if (f[i+(1 << (j-1))][j-1]>f[i][j]){ f[i][j]=f[i+(1 << (j-1))][j-1]; fid[i][j]=fid[i+(1 << (j-1))][j-1]; } // g[i][j]=min(g[i][j-1],g[i+(1 << (j-1))][j-1]); // f[i][j]=max(f[i][j-1],f[i+(1 << (j-1))][j-1]); } for (int i=1;i<=n;i++){ int t=(int)(log10((double)(len[i]-i+1))/log10(2.0)); int ma; if (f[i][t]>=f[len[i]-(1 << t)+1][t]) ma=fid[i][t];else ma=fid[len[i]-(1 << t)+1][t]; if (ma-i>maxlen) maxlen=ma-i; } // search(1,n); if (maxlen==0) printf("-1\n"); else if (maxlen<=k) printf("%d\n",maxlen); else printf("%d\n",maxlen-k); } return 0; }
Loongint的夜晚
【Description】
Loongint和MM在僻静的小镇上居住着,一天晚上,MM对Loongint说:“亲爱的,去把灯关掉。”Loongint十分兴奋,可发现MM亮了整整一排灯…Loongint必须关掉所有的灯…开始时他站在某一盏灯的旁边,每盏灯都有一个给定功率的电灯泡(!),因为Loongint有着自觉的节能意识(表扬),他希望在耗电能总数最少的情况下将所有的灯关掉。Loongint为了积攒精力,所以只能以1m/s的速度行走。关灯不需要花费额外的时间,因为当他通过时就能将灯关掉。
Loongint需要你在给定路灯设置和灯泡功率的情况下计算以及Loongint的起始位置的情况下关掉所有的灯需耗费的最小能量。
【Input】
输入文件的第一行包含一个整数N,2≤N≤1000,表示灯的数量。
第二行包含一个整数V,1≤V≤N,表示Loongint开始关灯的路灯号码。
接下来的N行中,每行包含两个用空格隔开的整数D和W,用来描述每盏灯的参数,其中0≤D≤1000,0≤W≤1000。D表示该灯与这排灯开始处的距离(用米为单位来表示),W表示灯泡的功率,即在每秒钟该灯泡所消耗的能量数。灯是按顺序给定的。
【Output】
输出文件的第一行即唯一的一行应包含一个整数,即消耗能量之和的最小值。注意结果不超过1,000,000,000。
【Sample Input】
4
3
2 2
5 8
6 1
8 7
【Sample Output】
56
#include <cstdio> #include <cstring> int n; int v; int f[1100][1100][2]; int d[1100]; int w[1100]; int sum[1100]; int min(int a,int b){return a<b?a:b;} int main(){ freopen("night.in","r",stdin); freopen("night.out","w",stdout); scanf("%d%d",&n,&v); for (int i=1;i<=n;i++){ scanf("%d%d",&d[i],&w[i]); sum[i]=sum[i-1]+w[i]; } memset(f,63,sizeof(f)); f[v][v][0]=f[v][v][1]=0; for (int i=v;i>0;i--){ for (int j=v;j<=n;j++){ if (i<v){ f[i][j][0]=min(f[i][j][0],f[i+1][j][0]+(d[i+1]-d[i])*(sum[n]-sum[j]+sum[i])); f[i][j][0]=min(f[i][j][0],f[i+1][j][1]+(d[j]-d[i])*(sum[n]-sum[j]+sum[i])); } if (j>v){ f[i][j][1]=min(f[i][j][1],f[i][j-1][1]+(d[j]-d[j-1])*(sum[n]-sum[j-1]+sum[i-1])); f[i][j][1]=min(f[i][j][1],f[i][j-1][0]+(d[j]-d[i])*(sum[n]-sum[j-1]+sum[i-1])); } } } int ans=f[1][n][0]<f[1][n][1]?f[1][n][0]:f[1][n][1]; printf("%d\n",ans); return 0; }