大学ACM考试题目及作业答案整理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ACM作业与答案整理
1、平面分割方法:设有n条封闭曲线画在平面上,而任何两条封闭曲线恰好相交于两点,且任何三条封闭曲线不相交于同一点,问这些封闭曲线把平面分割成的区域个数。
#include <iostream.h>
int f(int n)
{
if(n==1) return 2;
else return f(n-1)+2*(n-1);
}
void main()
{
int n;
while(1)
{
cin>>n;
cout<<f(n)<<endl;
}
}
2、LELE的RPG难题:有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.编程全部的满足要求的涂法.
#include<iostream.h>
int f(int n)
{
if(n==1) return 3;
else if(n==2) return 6;
else return f(n-1)+f(n-2)*2;
}
void main()
{
int n;
while(1)
{
cin>>n;
cout<<f(n)<<endl;
}
}
3、北大ACM(1942)
Paths on a Grid
Time Limit: 1000MS Memory Limit: 30000K Description
Imagine you are attending your math lesson at school. Once again, you are bored because your teacher tells things that you already mastered years ago (this time he's explaining that (a+b)2=a2+2ab+b2). So you decide to waste your time with drawing modern art instead.
Fortunately you have a piece of squared paper and you choose a rectangle of size n*m on the paper. Let's call this rectangle together with the lines it contains a grid. Starting at the lower left corner of the grid, you move your pencil to the upper right corner, taking care that it stays on the lines and moves only to the right or up. The result is shown on the left:
Really a masterpiece, isn't it? Repeating the procedure one more time, you arrive with the picture shown on the right. Now you wonder: how many different works of art can you produce?
Input
The input contains several testcases. Each is specified by two unsigned 32-bit integers n and m, denoting the size of the rectangle. As you can observe, the number of lines of the corresponding grid is one more in each dimension. Input is terminated by n=m=0.
Output
For each test case output on a line the number of different art works that can be generated using the procedure described above. That is, how many paths are there on a grid where each step of the path consists of moving one unit to the right or
one unit up? You may safely assume that this number fits into a 32-bit unsigned integer.
Sample Input
5 4
1 1
0 0
Sample Output
126
2
#include<iostream>
using namespace std;
longlong f(long long m, long long n)
{
if(n==0) return 1;
else return f(m-1,n-1)*m/n;
}
int main()
{
longlongm,n;
while(scanf("%I64d %I64d",&n,&m) &&n+m)
{
printf("%I64d\n",f(m+n,min(m,n)));
}
return 0;
}
1、(并查集)若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。
规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。
如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。
数据输入:
第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。
以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Ai和Bi具有亲戚关系。
接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。
数据输出:
P行,每行一个’Yes’或’No’。
表示第i个询问的答案为“具有”或“不具有”亲戚关系。
样例:
Input:
6 5 3
1 2
1 5
3 4
5 2
1 3
1 4
2 3
5 6
Output:
Yes
Yes
No
代码:
#include<stdio.h>
int father[10000];
int find(int x)
{
if(father[x]==x) return x;
else
return father[x]=find(father[x]);
}
int main()
{
intn,m,p;
scanf("%d%d%d",&n,&m,&p);
for(inti=1;i<=n;i++) father[i]=i;
inta,b;
for(inti=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
a=find(a);
b=find(b);
if(a!=b) father[a]=b;
}
for(inti=1;i<=p;i++)
{
scanf("%d%d",&a,&b);
a=find(a);
b=find(b);
if(a!=b)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}
假设有两个皇后被放置在(i,j)和(k,l)的位置上,明显,当且仅当|i-k|=|j-l| 时,两个皇后才在同一条对角线上。
(1)先从首位开始检查,如果不能放置,接着检查该行第二个位置,依次检查下去,直到在该行找到一个可以放置一个皇后的地方,然后保存当前状态,转到下一行重复上述方法的检索。
(2)如果检查了该行所有的位置均不能放置一个皇后,说明上一行皇后放置的位置无法让所有的皇后找到自己合适的位置,因此就要回溯到上一行,重新检查该皇后位置后面的位置。
具体的实现代码如下:
#include<iostream>
using namespace std;
intqizi[20];//qizi【i】=j表示第i行第j列下有棋
intans[11];//结果存到表中,不存会超时
int n;
int sum;
bool judge(int hang)
{
for(inti=1;i<hang;i++)//扫之前下过棋每一行是否有与此次所下棋的位置同列的或同对角线的
{
if(qizi[i]==qizi[hang]||abs(hang-i)==abs(qizi[hang]-qizi[i]))//对角线的话斜率的绝对值=1
return false;
}
return true;
}
voiddfs(int hang)
{
if(hang==n+1)//比如n=2,然后该第二行下棋了,第二行如果能成功选择的话,那么那么新的行数3就等于n+1=3了,实在不懂举个例子看看
sum++;
else
{
for(int j=1;j<=n;j++)//在该行选第几列
{
qizi[hang]=j;
if(judge(hang))
{
dfs(hang+1);//在本行能下棋的话,就接着下下一行的棋
}
}
}
}
int main()
{
for(n=1;n<=10;n++)
{
sum=0;
dfs(1);
ans[n]=sum;
}
int q;
while(scanf("%d",&q)!=EOF) {
if(q==0)
break;
printf("%d\n",ans[q]);
}
return 0;
}。