您的位置:首页 > 理论基础

2011年清华大学计算机研究生机试真题

2016-04-06 10:16 316 查看

题目1086:最小花费

题目描述:
在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对应关系如下:
距离s 票价
0<S<=L1 C1
L1<S<=L2 C2
L2<S<=L3 C3
输入保证0<L1<L2<L3<10^9,0<C1<C2<C3<10^9。
每两个站之间的距离不超过L3。
当乘客要移动的两个站的距离大于L3的时候,可以选择从中间一个站下车,然后买票再上车,所以乘客整个过程中至少会买两张票。
现在给你一个 L1,L2,L3,C1,C2,C3。然后是A B的值,其分别为乘客旅程的起始站和终点站。
然后输入N,N为该线路上的总的火车站数目,然后输入N-1个整数,分别代表从该线路上的第一个站,到第2个站,第3个站,……,第N个站的距离。
根据输入,输出乘客从A到B站的最小花费。

输入:
以如下格式输入数据:
L1 L2 L3 C1 C2 C3
A B
N
a[2]
a[3]
……
a

输出:
可能有多组测试数据,对于每一组数据,
根据输入,输出乘客从A到B站的最小花费。

样例输入:
1 2 3 1 2 3
1 2
2
2


样例输出:
2


算法分析:动态规划, dp[j]=min(dp[i]+cost(dis[i],dis[j]));是状态转移方程。

#include<iostream>
#include<math.h>
#include<stdlib.h>
using namespace std;
long long c1,c2,c3,s1,s2,s3;
long long a,b,n;
long long dp[10005];//到达第i站用的费用
long long dis[10005];//该线路上的第一个站到第i个站的距离
long long cost(long long a,long long b)//计算两个站之间的花费
{
if(abs(a-b)<=s1)
return c1;
if(abs(a-b)<=s2&&abs(a-b)>s1)//fabs是求解浮点数的绝对值,而abs是求解整数的绝对值
return c2;
if(abs(a-b)<=s3&&abs(a-b)>s2)
return c3;
}
int main()
{
while(cin>>s1>>s2>>s3>>c1>>c2>>c3)
{
cin>>a>>b;
cin>>n;
dis[1]=0;
for(int i=2;i<=n;i++)
cin>>dis[i];
for(int i=0;i<=10005;i++)
dp[i]=1000000000000;//将所有的费用初始化最大
dp[a]=0;//在出发站处费用是0;
for(int i=a;i<=b;i++)
{
for(int j=i+1;dis[j]-dis[i]<=s3&&j<=b;j++)
{
if(dp[j]>dp[i]+cost(dis[i],dis[j]))//状态转移方程
dp[j]=dp[i]+cost(dis[i],dis[j]);//注意不是cost(i,j)
}
}
cout<<dp<<endl;
}
return 0;
<dl class="main-title-mod mb10"><dt class="title-hd">
</dt></dl>}



题目1087:约数的个数

[b]题目描述:

输入n个整数,依次输出每个数的约数的个数

输入:
输入的第一行为N,即数组的个数(N<=1000)

接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)

当N=0时输入结束。

输出:
可能有多组输入数据,对于每组输入数据,

输出N行,其中每一行对应上面的一个数的约数的个数。

样例输入:
5
1 3 4 6 12


样例输出:
1
2
3
4
6


//可以直接暴力求解
#include <iostream>
#include <cmath>
using namespace std;
int main(void)
{
int n;
while (cin >> n)
{
int num;
while (n--)
{
int count = 0;
cin >> num;
int i;
for (i = 1; i < sqrt((double)num); i++)
{
if (num % i == 0)
{
count += 2;
}
}
if (i * i == num)//如果是平方数则加1
{
count++;
}
cout << count << endl;
}
}
return 0;
}


题目1088:剩下的树

题目描述:

有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,...,L共L+1个位置上有L+1棵树。

现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。

可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。

输入:
两个整数L(1<=L<=10000)和M(1<=M<=100)。

接下来有M组整数,每组有一对数字。

输出:
可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。

样例输入:
500 3
100 200
150 300
470 471


样例输出:
298


/*
题目描述:
有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,
在每个整数坐标点有一棵树,即在0,1,2,...,L共L+1个位置上有L+1棵树。
现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。
可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。
输入:
两个整数L(1<=L<=10000)和M(1<=M<=100)。
接下来有M组整数,每组有一对数字。
输出:
可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。
*/
#include <stdio.h>
#include <string.h>
int main()
{
int L,M;
int start,end;
int i,j,ans;
int a[10001];

while(scanf("%d%d",&L,&M)!=EOF)
{
memset(a,0,sizeof(a));
for(i=0;i<M;++i)
{
scanf("%d%d",&start,&end);
for(j=start;j<=end;++j)
a[j]=1;
}

ans=0;
for(i=0;i<=L;++i)
{
if(a[i]==0)
ans++;
}

printf("%d\n",ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: