九度OJ题目传送门:2011年北京大学计算机研究生机试真题
一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,每行一个正整数a (a < 32768)
输出包含n行,每行对应一个输入,包含两个正整数,第一个是最少的动物数,第二个是最多的动物数,两个正整数用一个空格分开
如果没有满足要求的答案,则输出两个0。
2
3
20
0 0
5 10
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int n, a;
scanf("%d", &n);
while(n--){
scanf("%d", &a);
int t1 = a/2;
int t2 = a/4;
int maxn = 0, minn = 0;
for(int i = 0; i <= t1; i++){
for(int j = 0; j <= t2; j++){
if(i*2+j*4==a){
if(minn==0)
minn = i+j;
if(i+j>maxn)
maxn = i+j;
if(i+j<minn)
minn = i+j;
}
}
}
printf("%d %d\n", minn, maxn);
}
return 0;
}
/************************************************************** Problem: 1155 User: violet0908 Language: C++ Result: Accepted Time:330 ms Memory:1020 kb ****************************************************************/
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
对输入的每组数据M和N,用一行输出相应的K。
1
7 3
8
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int fun(int m, int n){
if(n == 1)
return 1;
if(m==1 || m==0)
return 1;
else if(m < 0)
return 0;
else
return fun(m, n-1)+fun(m-n, n);
}
int main()
{
int t, m, n;
scanf("%d", &t);
while(t--){
scanf("%d %d", &m, &n);
printf("%d\n", fun(m, n));
}
return 0;
}
/************************************************************** Problem: 1160 User: violet0908 Language: C++ Result: Accepted Time:0 ms Memory:1020 kb ****************************************************************/
“臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为一个宅男,你发现自己与他人相互了解的机会并不太多。幸运的是,你意外得到了一份北大图书馆的图书借阅记录,于是你挑灯熬夜地编程,想从中发现潜在的朋友。
首先你对借阅记录进行了一番整理,把N个读者依次编号为1,2,…,N,把M本书依次编号为1,2,…,M。同时,按照“臭味相投”的原则,和你喜欢读同一本书的人,就是你的潜在朋友。你现在的任务是从这份借阅记录中计算出每个人有几个潜在朋友。
每个案例第一行两个整数N,M,2 <= N ,M<= 200。接下来有N行,第i(i = 1,2,…,N)行每一行有一个数,表示读者i-1最喜欢的图书的编号P(1<=P<=M)
每个案例包括N行,每行一个数,第i行的数表示读者i有几个潜在朋友。如果i和任何人都没有共同喜欢的书,则输出“BeiJu”(即悲剧,^ ^)
4 5
2
3
2
1
1
BeiJu
1
BeiJu
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[250];
int p[250];
int main()
{
int n, m;
while(scanf("%d %d", &n, &m)!=EOF){
memset(f, 0, sizeof(f));
for(int i = 0; i < n; i++){
scanf("%d", &p[i]);
f[p[i]]++;
}
for(int i = 0; i < n; i++){
if(f[p[i]]==1){
printf("BeiJu\n");
}
else if(f[p[i]]>1){
printf("%d\n", f[p[i]]-1);
}
}
}
return 0;
}
/************************************************************** Problem: 1156 User: violet0908 Language: C++ Result: Accepted Time:0 ms Memory:1024 kb ****************************************************************/
中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数(或最中间两个数据的平均数).
给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)
该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1<=N<=10000.
接着N行为N个数据的输入,N=0时结束输入
输出中位数,每一组测试数据输出一行
4
10
30
20
40
3
40
30
50
4
1
2
3
4
0
25
40
2
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int n;
int num[10005];
while(scanf("%d", &n)!=EOF){
if(n==0)
break;
for(int i = 0; i < n; i++)
scanf("%d", &num[i]);
sort(num, num+n);
int ans;
if(n%2==1){
ans = num[n/2];
}
else{
ans = (num[n/2-1]+num[n/2])/2;
}
printf("%d\n", ans);
}
return 0;
}
/**************************************************************
Problem: 1157
User: violet0908
Language: C++
Result: Accepted
Time:20 ms
Memory:1020 kb
****************************************************************/
某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每年百分之K增长,并且该程序员未来年薪不变,且不吃不喝,不用交税,每年所得N万全都积攒起来,问第几年能够买下这套房子(第一年房价200万,收入N万)
有多行,每行两个整数N(10<=N<=50), K(1<=K<=20)
针对每组数据,如果在第20年或者之前就能买下这套房子,则输出一个整数M,表示最早需要在第M年能买下,否则输出Impossible,输出需要换行
50 10
40 10
40 8
8
Impossible
10
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
double cnt, n, k, sum;
while(scanf("%lf %lf", &n, &k)!=EOF){
sum = n;
cnt = 1;
int fang = 200;
int flag = 1;
while(sum < fang){
fang = (1+k/100)*fang;
sum+=n;
cnt++;
if(cnt > 20){
printf("Impossible\n");
flag = 0;
break;
}
}
if(flag==1){
printf("%.0lf\n", cnt);
}
}
return 0;
}
/**************************************************************
Problem: 1158
User: violet0908
Language: C++
Result: Accepted
Time:0 ms
Memory:1020 kb
****************************************************************/
The country is facing a terrible civil war—-cities in the country are divided into two parts supporting different leaders. As a merchant, Mr. M does not pay attention to politics but he actually knows the severe situation, and your task is to help him reach home as soon as possible.
“For the sake of safety,”, said Mr.M, “your route should contain at most 1 road which connects two cities of different camp.”
Would you please tell Mr. M at least how long will it take to reach his sweet home?
The input contains multiple test cases.
The first line of each case is an integer N (2<=N<=600), representing the number of cities in the country.
The second line contains one integer M (0<=M<=10000), which is the number of roads.
The following M lines are the information of the roads. Each line contains three integers A, B and T, which means the road between city A and city B will cost time T. T is in the range of [1,500].
Next part contains N integers, which are either 1 or 2. The i-th integer shows the supporting leader of city i.
To simplify the problem, we assume that Mr. M starts from city 1 and his target is city 2. City 1 always supports leader 1 while city 2 is at the same side of leader 2.
Note that all roads are bidirectional and there is at most 1 road between two cities.
Input is ended with a case of N=0.
For each test case, output one integer representing the minimum time to reach home.
If it is impossible to reach home according to Mr. M’s demands, output -1 instead.
2
1
1 2 100
1 2
3
3
1 2 100
1 3 40
2 3 50
1 2 1
5
5
3 1 200
5 3 150
2 5 160
4 3 170
4 2 170
1 2 2 2 1
0
100
90
540
思路:刚开始真想不出来,考虑的很复杂,最后参考了网上的题解后恍然大悟,对于不是同一个阵营的路换成单向的就简单了,同一个阵营的路还是双向路
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0xffffff
#define MAXN 605
using namespace std;
int mp[MAXN][MAXN], dis[MAXN], team[MAXN];
bool vis[MAXN];
void dijkstra(int s, int n){
memset(vis, false, sizeof(vis));
for(int i = 1; i <= n; i++)
dis[i] = mp[s][i];
vis[s] = true;
dis[s] = 0;
for(int i = 1; i < n; i++){
int min = INF, pos;
for(int j = 1; j <= n; j++){
if(!vis[j] && dis[j] < min){
min = dis[j];
pos = j;
}
}
if(min == INF)
break;
vis[pos] = true;
for(int j = 1; j <= n; j++){
if(!vis[j] && dis[pos]+mp[pos][j] < dis[j]){
dis[j] = dis[pos] + mp[pos][j];
}
}
}
if(dis[2] < INF)
printf("%d\n", dis[2]);
else
printf("-1\n");
}
int main()
{
int n, m;
while(scanf("%d", &n)!=EOF){
if(n == 0)
break;
scanf("%d", &m);
for(int i = 0; i < MAXN; i++)
for(int j = 0; j < MAXN; j++)
mp[i][j] = INF;
for(int i = 0; i < m; i++){
int x, y, t;
scanf("%d %d %d", &x, &y, &t);
mp[x][y] = mp[y][x] = t;
}
for(int i = 1; i <= n; i++)
scanf("%d", &team[i]);
for(int i = 1; i<=n; i++){
for(int j = i+1; j <= n; j++){
if(team[i]==team[j]) //如果是同一个阵营,就不做操作
continue;
else if(team[i]==1 && team[j]==2) //如果不是同一个阵营,就简历单向边
mp[j][i] = INF;
else if(team[i]==2 && team[j]==1)
mp[i][j] = INF;
}
}
dijkstra(1, n);
}
return 0;
}