会场安排问题
问题描述:
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。)
编程任务:
对于给定的k 个待安排的活动,编程计算使用最少会场的时间表。
数据输入:
第一行有1 个正整数k,表示有k 个待安排的活动。接下来的k 行中,每行有2 个正整数,分别表示k 个待安排的活动开始时间和结束时间。时间以0 点开始的分钟计。
结果输出:
输出最少会场数 。
输入示例 输出示例
5 3
1 23
12 28
25 35
27 80
36 50
#include<bits/stdc++.h>
using namespace std;
int n,Begins[1000],Ends[1000];
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>Begins[i]>>Ends[i];
}
sort(Begins,Begins+n);
sort(Ends,Ends+n);
int j=0,ans=0;
for(int i=0;i<n;i++)
{
if(Begins[i]<Ends[j]) ans++;
else j++;
}
cout<<ans;
return 0;
}
硬币找钱问题
问题描述:
设有6 种不同面值的硬币,各硬币的面值分别为5 分,1 角,2 角,5 角,1 元,2 元。现要用这些面值的硬币来购物和找钱。购物时可以使用的各种面值的硬币个数存于数组Coins[1:6 ]中,商店里各面值的硬币有足够多。在1 次购物中希望使用最少硬币个数。
例如,1 次购物需要付款0.55 元,没有5 角的硬币,只好用2*20+10+5 共4 枚硬币来付款。如果付出1 元,找回4 角5 分,同样需要4 枚硬币。但是如果付出1.05 元(1 枚1 元和1 枚5 分),找回5 角,只需要3 枚硬币。这个方案用的硬币个数最少。
编程任务:
对于给定的各种面值的硬币个数和付款金额,编程计算使用硬币个数最少的交易方案。
数据输入:
每一行有6 个整数和1 个有2 位小数的实数。分别表示
可以使用的各种面值的硬币个数和付款金额。以6 个0 结束。
结果输出:
输出最少硬币个数。结果应分行输出,每行一个数据。如果不可能完成交易,则输出”impossible”。
输入示例
2 4 2 2 1 0 0.95
2 4 2 0 1 0 0.55
0 0 0 0 0 0
输出示例
2
3
#include<bits/stdc++.h>
using namespace std;
int coins[6];
int coinNum=0;
int pay,realMoney;
int coinsValue[6]={5,10,20,50,100,200};
int changeValue[7]={0,5,10,20,50,100,200};
int contains(int a)
{
for(int i=0;i<6;i++)
{
if(coinsValue[i]==a&&coins[i]>0)
{
return i;
}
}
return -1;
}
void greed()
{
int TempCoinNum=0;
for(int i=5;i>=0;i--)
{
if(coins[i]>0)
{
for(int j=0;j<=i;j++)
{
realMoney=coinsValue[i]-changeValue[j];
if(pay>=realMoney)
{
if(coins[i]>=pay/realMoney)
{
int TempCoinNum=pay/realMoney;
coinNum+=TempCoinNum*2;
if(contains(realMoney)!=-1)
{
TempCoinNum=min(TempCoinNum,coins[contains(realMoney)]);
coinNum-=TempCoinNum;
coins[contains(realMoney)]-=TempCoinNum;
}
else coins[i]-=pay/realMoney;
pay=pay%realMoney;
if(contains(coinsValue[i])==-1) break;
}
else
{
coinNum+=coins[i];
pay=pay-coinsValue[i]*coins[i];
coins[i]=0;
}
}
}
}
}
}
int main()
{
while(!cin.eof())
{
coinNum=0;
for(int i=0;i<6;i++)
{
cin>>coins[i];
}
if(coins[0]==0&&coins[1]==0&&coins[2]==0&&coins[3]==0&&coins[4]==0&&coins[5]==0) break;
double cost;
cin>>cost;
pay=int(cost*100);
greed();
if(coinNum==0||pay!=0) cout<<"impossible"<<endl;
else cout<<coinNum<<endl;
}
return 0;
}
汽车加油问题
问题描述:
一辆汽车加满油后可行驶n 公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。
编程任务:
对于给定的n 和k 个加油站位置,编程计算最少加油次数。
数据输入:
第一行有2 个正整数n 和k,表示汽车加满油后可行驶n 公里,且旅途中有k 个加油站。接下来的1 行中,有k+1 个整数,表示第k 个加油站与第k-1 个加油站之间的距离。第0 个加油站表示出发地,汽车已加满油。第k+1 个加油站表示目的地。
结果输出:
输出最少加油次数。如果无法到达目的地,则输出”No Solution”。
输入示例 输出示例
7 7 4
1 2 3 4 5 1 6 6
#include<bits/stdc++.h>
using namespace std;
int n,k,s[1000];
int num;
int main()
{
cin>>n>>k;
for(int i=0;i<=k;i++)
{
cin>>s[i];
}
int x=s[0];
for(int i=1;i<=k;i++)
{
if(x>n)
{
cout<<"No Solution!";
break;
}
else
{
x=x+s[i];
if(x>n)
{
num++;
x=s[i];
cout<<"在第"<<i<<"个加油站加油"<<endl;
}
}
}
cout<<num;
return 0;
}
最优分解问题
问题描述:
设n 是一个正整数。现在要求将n 分解为若干个互不相同的自然数的和,且使这些自然数的乘积最大。
编程任务:
对于给定的正整数n,编程计算最优分解方案。
数据输入:
第1 行是正整数n。
结果输出:
输出最大乘积。
输入示例 输出示例
10 30
#include<bits/stdc++.h>
using namespace std;
int n;
int a[1000];
int res=1;
int main()
{
cin>>n;
int i=2;
int sum=0,index=0;
while(n-sum>=i)
{
sum+=i;
a[i]=i;
i++;
index++;
}
int p=(n-sum)/index;
int q=(n-sum)%index;
for(int j=i-1;j>=2;j--)
{
a[j]+=p;
}
for(int k=i-1;k>i-1-q;k--)
{
a[k]++;
}
for(int j=2;j<index+2;j++)
{
res=res*a[j];
}
cout<<res;
return 0;
}
程序存储问题
问题描述:
设有n 个程序{1,2,…, n }要存放在长度为L 的磁带上。程序i 存放在磁带上的长度是li,1≤i≤n 。程序存储问题要求确定这n 个程序在磁带上的一个存储方案,使得能够在磁带上存储尽可能多的程序。
编程任务:
对于给定的n 个程序存放在磁带上的长度,编程计算磁带上最多可以存储的程序数。
数据输入:
第一行是2 个正整数,分别表示文件个数n 和磁带的长度L。接下来的1 行中,有n 个正整数,表示程序存放在磁带上的长度。
结果输出:
输出最多可以存储的程序数。
输入示例 输出示例
6 50 5
2 3 13 8 80 20
#include<bits/stdc++.h>
using namespace std;
int n,l,len[1000],num;
int main()
{
cin>>n>>l;
for(int i=0;i<n;i++)
{
cin>>len[i];
}
sort(len,len+n);
for(int i=0;i<n;i++)
{
if(l>len[i])
{
l=l-len[i];
num++;
}
else break;
}
cout<<num;
return 0;
}