> 文章列表 > Contest3070 - 计科2101~2104算法设计与分析上机作业05

Contest3070 - 计科2101~2104算法设计与分析上机作业05

Contest3070 - 计科2101~2104算法设计与分析上机作业05

问题 A: 最小平均等待时间

题目描述

有n个顾客同时在等待一项服务,顾客i需要的服务时间为ti,1≤i≤n。要安排一个服务次序使得平均等待时间最小(平均等待时间是n个顾客等待服务时间的总和除以n)。请编写算法,计算最小平均等待时间。

输入

第一行为测试用例个数m,m≤1000。 第二行开始为m个测试用例,每个测试用例由一组空格间隔的整数组成,第一个整数n为顾客的人数,后面n个整数为每个顾客需要的服务时间t,0<m≤1000,0<t≤1000。

输出

对每个测试用例,输出最小平均等待时间的整数部分(舍去小数部分),每个输出占一行。

样例输入 复制

2
5 15 9 3 14 3
10 13 3 12 9 6 9 1 91 44 32

样例输出 复制

10
36

欸,这不就是短作业优先的调度算法嘛

#include<bits/stdc++.h>
using namespace std;int main() {int t;cin>>t;while(t--){int n;cin>>n;int a[n];for(int i=0; i<n; i++)cin>>a[i];sort(a,a+n);int sum=0;int ans=0;for(int i=1; i<n; i++) {sum+=a[i-1];ans+=sum;}cout<<ans/n<<endl;
}return 0;
}

 问题 B: 最少货币支付问题

题目描述

现行的货币体系为(1、2、5、10、20、50、100),请设计算法,计算要用最少的货币数支付指定金额N,每种货币需要使用的数量。

输入

第一行为测试用例个数n,n≤1000。 后面n行,每行为一个测试用例,每个测试用例为一个大于0的整数目标金额m,0≤m≤10000。

输出

对每个测试用例,输出一行由空格间隔的7个整数,分别表示1元、2元、5元、10元、20元、50元、100元所使用的数量。

样例输入 复制

2
15
189

样例输出 复制

0 0 1 1 0 0 0 
0 2 1 1 1 1 1 

 

#include<bits/stdc++.h>
int main()
{int n,N;scanf("%d",&N);while(N--){int a=0,b=0,c=0,d=0,e=0,f=0,g=0;scanf("%d",&n);while(n>=100){g=g+1;n=n-100;}while(n>=50&&n<100){f=f+1;n=n-50;			}while(n>=20&&n<50){e=e+1;n=n-20;			}while(n>=10&&n<20){d=d+1;n=n-10;			}while(n>=5&&n<10){c=c+1;n=n-5;			}while(n>=2&&n<5){b=b+1;n=n-2;			}if(n>0&&n<2){a=1;}printf("%d %d %d %d %d %d %d\\n",a,b,c,d,e,f,g);}} 

问题 C: 活动安排

题目描述

样例输入 

4
1 3
4 6
2 5
1 7

样例输出 

2

提示

1≤n≤1000

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
struct ac {int start;int end;
};bool cmp(ac a, ac b){return a.end < b.end;
}int main(){int n;cin >> n;ac a[1005];for (int i = 0; i < n; i++){cin >> a[i].start >> a[i].end;}sort(a, a + n, cmp);int ans = 1;int k = a[0].end;int loc = 0;for (int i = 1; i < n; i++){if (a[i].start >= a[loc].end){ans++;k=a[i].end;loc = i;}}cout << ans << endl;
}

 问题 D: 数列极差

 

题目描述

小源的老师在黑板上写了一个由n个正整数组成的数列,要求小源进行如下操作:每次擦去其中的两个数a和b,然后在数列中加入一个数 a*b+1,如此下去直至黑板上剩下一个数为止,在所有按这种操作方式最后得到的数中,最大的为max,最小的为min, 则该数列的极差定义为 M=max-min.
由于小源忙于准备期末考试,现请你帮助她,对于给定的数列,计算出相应的极差M。

输入

第一行为一个正整数n表示正整数序列的长度;
在接下来的n行中,每行输入一个正整数。
接下来的一行有一个0,表示数据结束。

输出

输出只有一行,为相应的极差d。

样例输入 复制

3
1
2
3
0

样例输出 复制

2

提示

对于全部数据,0≤n≤50000,保证所有数据计算均在 32 位有符号整数范围内。

 

#include <bits/stdc++.h>
#define rush() int T;cin>>T;while(T--)
#define go(a) while(cin>>a)
#define ms(a,b) memset(a,b,sizeof a)
#define E 1e-8
#define debug(a) cout<<"*"<<a<<"*"<<endl
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<double,double> Pair;
const int inf=0x3f3f3f3f;
const int N=1e4+5;int n,m,t;int i,j,k;//int a[N];priority_queue<int,vector<int>,greater<int> >maxx;priority_queue<int,vector<int>,less<int> >minn;
int main()
{IOS;while(cin>>n){for(i=0;i<n;i++){int x; cin>>x;maxx.push(x); minn.push(x);}int a,b;while(maxx.size()>1){a=maxx.top(); maxx.pop();b=maxx.top(); maxx.pop();maxx.push(a*b+1);}while(minn.size()>1){a=minn.top(); minn.pop();b=minn.top(); minn.pop();minn.push(a*b+1);}cout<<maxx.top()-minn.top()<<endl; break;}return 0;
}

 问题 E: 钓鱼

题目描述

在一条水平路边,有n个钓鱼湖,从左到右编号为1,2,…,n。庄dalao有H个小时的空余时间,他希望利用这个时间钓到更多的鱼。他从1出发,向右走,有选择的在一些湖边停留一定的时间(是5分钟的倍数)钓鱼。最后在某一个湖边结束钓鱼。庄dalao从第i个湖到第i+1个湖需要走5×Ti分钟路,还测出在第i个湖停留,第一个5分钟可以钓到Fi条鱼,以后每再钓5分钟,可以钓到的鱼量减少Di,若减少后的鱼量小于0,则减少后的鱼量为0。为了简化问题,庄dalao假定没有其他人钓鱼,也没有其他因素影响他钓到期望数量的鱼。请编程求出庄dalao最多能钓鱼的数量。

输入

第一行一个整数n,表示湖的个数,不大于25
第二行一个整数H,表示庄dalao的空闲时间,不大于20
第三行有n个整数,依次表示每个湖第一个5分钟能钓到鱼的数量 ,不大于100
第四行有n个整数,依次表示以后的每5分钟钓鱼数量比前一个5分钟钓鱼数量减少的数量
第五行有n-1个整数,Ti表示由第i个湖到第i+1个湖需要花5×Ti分钟的路程
保证在int以内

输出

输出只有一行,表示庄dalao最多能钓鱼的数量。

样例输入 复制

3
1
4 5 6
1 2 1
1 2

样例输出 复制

35

提示

#include <bits/stdc++.h>
#define rush() int T;cin>>T;while(T--)
#define go(a) while(cin>>a)
#define ms(a,b) memset(a,b,sizeof a)
#define E 1e-8
#define debug(a) cout<<"*"<<a<<"*"<<endl
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define s first
#define e second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> Pair;
const int inf=0x3f3f3f3f;
const int N=1e3+5;int n,m,t;int i,j,k;int fish[N],d[N],dis[N];priority_queue< Pair >q;int main()
{IOS; string s;int n;cin>>n;int t; cin>>t;  t*=60;for(i=1;i<=n;i++) cin>>fish[i];for(i=1;i<=n;i++) cin>>d[i];for(i=2;i<=n;i++)  cin>>dis[i];int ans=-1,waste=0;for(i=1;i<=n;i++){int maxx=0;for(j=1;j<=i;j++){q.push(make_pair(fish[j],j));}int rest=t-waste;while(rest>0&&q.top().first>0){Pair p=q.top(); q.pop();maxx+=p.first;p.first-=d[p.second];q.push(p);rest-=5;}ans=max(maxx,ans);waste+=dis[i+1]*5;while(!q.empty()) q.pop();}cout<<ans<<endl;return 0;
}

 问题 F: N后问题(回溯法)

题目描述

在N*N的类似国际象棋棋盘上,要放置N个王后,要求任两个王后之间不能互相攻击,也就是任两个王后不共线。 问有多少种摆放的方法?

输入

输入为一组整数,每行为一个整数n,n<=10,最后一行是一个0。

输出

对每个整数n(不包括结尾行的0),计算摆放王后的方法,并输出方案个数,每个输出占一行。

样例输入 复制

2
4
0

样例输出 复制

0
2
#include<iostream>
#include <cmath>
using namespace std;
int N;
int ans=0;
int colqueen[1000];
void NQueen(int k);
int main()
{while(cin >> N){ans=0;if(N==0)break;int k=0;NQueen(k);cout<<ans<<endl;}return 0;
}
void NQueen(int k)
{if(k==N){ans++;return;}for(int i=0;i<N;i++)//列{int j;for(j=0;j<k;j++)//row{if(colqueen[j]==i||fabs(colqueen[j]-i)==fabs(k-j)){break;}}if(j==k){colqueen[k]=i;NQueen(k+1);}}
}