6-1 两顶点之前有路径吗? (20 分)
对于给定的无向图及两个图中的顶点,请实现一个函数,分别打印包含这两个顶点的连通分量中的顶点数,并判断这两个顶点之间是否有路径。
函数接口定义:
int hasPath(struct Graph *g, int v, int w);
其中v和w是顶点
图定义如下:
#define MaxVertexNum 20 /* 最大顶点数 */
struct Graph{
int v; /* 顶点数量 */
int Adj[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
题目保证图至少有一个顶点
函数分别在第一行和第二行打印包含v和w的连通分量中顶点的数量。
如果 v和w之间有路径,函数返回1, 否则返回0.
提示:
- 你可以定义多个函数,也可以定义全局变量.
- 当v和w是同一个顶点时,认为v和w之间是有路径的。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 20 /* 最大顶点数设为20 */
struct Graph{
int v; // amount of vertices
int Adj[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
int visited[MaxVertexNum]; /* 顶点的访问标记 */
struct Graph* CreateGraph(){
int v;
scanf("%d",&v);
struct Graph* g;
g = malloc(sizeof(struct Graph));
if(!g) return NULL;
g->v = v;
for(int i=0; i<v; i++){
visited[i] = 0;
for(int j=0; j<v; j++)
scanf("%d",&(g->Adj[i][j]));
}
return g;
}
int hasPath(struct Graph *g, int v, int w);
int main(){
struct Graph* g;
g = CreateGraph();
int v,w;
scanf("%d%d", &v, &w);
printf("%s\n", hasPath(g,v,w) ? "Yes" : "No");
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
对于此图及样例测试程序规定的输入格式:
8
0 1 1 0 0 0 0 1
1 0 0 0 1 0 0 0
1 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 1 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
1 3
Sample Output:
5
2
No
代码:
int hasPath(struct Graph *g, int v, int w){
int cnt1=0,cnt2=0;
int first=-1,last=-1;
int Q[MaxVertexNum];
for(int i=0;i<MaxVertexNum;i++){
visited[i]=0;
}
Q[++last]=v;
visited[v]=1;
cnt1++;
while(first!=last){
v=Q[++first];
for(int i=0;i<g->v;i++){
if(g->Adj[v][i]==1&&visited[i]==0){
Q[++last]=i;
visited[i]=1;
cnt1++;
}
}
}
printf("%d\n",cnt1);
for(int i=0;i<MaxVertexNum;i++){
visited[i]=0;
Q[i]=0;
}
first=-1,last=-1;
Q[++last]=w;
visited[w]=1;
cnt2++;
while(first!=last){
w=Q[++first];
for(int i=0;i<g->v;i++){
if(g->Adj[w][i]==1&&visited[i]==0){
Q[++last]=i;
visited[i]=1;
cnt2++;
}
}
}
printf("%d\n",cnt2);
if(g->Adj[v][w]==1||v==w){
return 1;
}
return 0;
}
7-1 多项式的加法 (20 分)
用链表表示多项式,并实现多项式的加法运算
输入格式:
输入在第一行给出第一个多项式POLYA的系数和指数,并以0,0 结束第一个多项式的输入;在第二行出第一个多项式POLYB的系数和指数,并以0,0 结束第一个多项式的输入。
输出格式:
对每一组输入,在一行中输出POLYA+POLYB和多项式的系数和指数。
输入样例:
5,0 2,1 1,6 8,15 0,0
-2,1 3,6 4,8 0,0
输出样例:
5,0 4,6 4,8 8,15
偷懒代码:
#include<iostream>
#include<map>
using namespace std;
map<int,int>mp;
map<int,int>::iterator it;
int main(){
int a,b;
char c;
while(cin>>a>>c>>b){
if(a==0&&b==0){
break;
}
mp[b]=a;
}
while(cin>>a>>c>>b){
if(a==0&&b==0){
break;
}
mp[b]+=a;
}
for(it=mp.begin();it!=mp.end();it++){
if(it->second!=0){
cout<<it->second<<","<<it->first<<" ";
}
}
cout<<endl;
return 0;
}
7-2 括号配对 (20 分)
设表达式中允许包含3种括号:圆括号、方括号和大括号。即小括号、中括号和大括号。 编写一个算法来判断表达式中的括号是否正确配对,要求利用栈的结构实现。
输入格式:
输入一行带圆括号、方括号和大括号的字符串。
输出格式:
若匹配,输出yes。若不匹配,输出no。
输入样例1:
([1+2])
输出样例1:
yes
输入样例2:
([
输出样例2:
no
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<stack>
#include<cstdio>
using namespace std;
#define MAXN 10100
stack<char>st;
int main(){
string s;
cin>>s;
int flag=0;
for(int i=0;i<s.length();i++){
if(s[i]=='('||s[i]=='{'||s[i]=='['){
st.push(s[i]);
}else if(s[i]==')'){
if(st.top()=='('){
st.pop();
}else{
flag=1;
break;
}
}else if(s[i]==']'){
if(st.top()=='['){
st.pop();
}else{
flag=1;
break;
}
}else if(s[i]=='}'){
if(st.top()=='{'){
st.pop();
}else{
flag=1;
break;
}
}
}
if(st.size()==0&&flag==0){
cout<<"yes"<<endl;
}else{
cout<<"no"<<endl;
}
return 0;
}
7-3 串的模式匹配 (20 分)
给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出。如果找不到,则输出“Not Found”。
本题旨在测试各种不同的匹配算法在各种数据情况下的表现。各组测试数据特点如下:
数据0:小规模字符串,测试基本正确性;
数据1:随机数据,String 长度为 105,Pattern 长度为 10;
数据2:随机数据,String 长度为 105,Pattern 长度为 102;
数据3:随机数据,String 长度为 105,Pattern 长度为 103;
数据4:随机数据,String 长度为 105,Pattern 长度为 104;
数据5:String 长度为106,Pattern 长度为 105;测试尾字符不匹配的情形;
数据6:String 长度为 106,Pattern 长度为 105;测试首字符不匹配的情形。
输入格式:
输入第一行给出 String,为由英文字母组成的、长度不超过 106 的字符串。第二行给出一个正整数 N(≤10),为待匹配的模式串的个数。随后 N 行,每行给出一个 Pattern,为由英文字母组成的、长度不超过 105 的字符串。每个字符串都非空,以回车结束。
输出格式:
对每个 Pattern,按照题面要求输出匹配结果。
输入样例:
abcabcabcabcacabxy
3
abcabcacab
cabcabcd
abcabcabcabcacabxyz
输出样例:
abcabcacabxy
Not Found
Not Found
代码:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
#define MAXN 1000010
int main(){
char s[MAXN],t[MAXN];
cin>>s;
int n;
cin>>n;
char *p;
for(int i=0;i<n;i++){
cin>>t;
p=strstr(s,t);
if(p){
cout<<p<<endl;
}else{
cout<<"Not Found"<<endl;
}
}
return 0;
}
7-4 找鞍点 (20 分)
一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。
本题要求编写程序,求一个给定的n阶方阵的鞍点。
输入格式:
输入第一行给出一个正整数n(1≤n≤6)。随后n行,每行给出n个整数,其间以空格分隔。
输出格式:
输出在一行中按照“行下标 列下标”(下标从0开始)的格式输出鞍点的位置。如果鞍点不存在,则输出“NONE”。题目保证给出的矩阵至多存在一个鞍点。
输入样例1:
4
1 7 4 1
4 8 3 6
1 6 1 2
0 7 8 9
输出样例1:
2 1
输入样例2:
2
1 7
4 1
输出样例2:
NONE
代码:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
#define MAXN 10
int a[MAXN][MAXN];
int hang[MAXN],lie[MAXN];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
memset(hang,0,sizeof(hang));
memset(lie,1000000,sizeof(lie));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
hang[i]=max(hang[i],a[i][j]);
lie[i]=min(lie[i],a[j][i]);
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(a[i][j]==hang[i]&&a[i][j]==lie[j]){
cout<<i<<" "<<j<<endl;
return 0;
}
}
}
cout<<"NONE"<<endl;
return 0;
}
7-5 哈夫曼编码 (20 分)
给定一段文字,如果我们统计出字母出现的频率,是可以根据哈夫曼算法给出一套编码,使得用此编码压缩原文可以得到最短的编码总长。然而哈夫曼编码并不是唯一的。例如对字符串"aaaxuaxz",容易得到字母 ‘a’、‘x’、‘u’、‘z’ 的出现频率对应为 4、2、1、1。我们可以设计编码 {‘a’=0, ‘x’=10, ‘u’=110, ‘z’=111},也可以用另一套 {‘a’=1, ‘x’=01, ‘u’=001, ‘z’=000},还可以用 {‘a’=0, ‘x’=11, ‘u’=100, ‘z’=101},三套编码都可以把原文压缩到 14 个字节。但是 {‘a’=0, ‘x’=01, ‘u’=011, ‘z’=001} 就不是哈夫曼编码,因为用这套编码压缩得到 00001011001001 后,解码的结果不唯一,“aaaxuaxz” 和 “aazuaxax” 都可以对应解码的结果。本题就请你判断任一套编码是否哈夫曼编码。
输入格式:
首先第一行给出一个正整数 N(2≤N≤63),随后第二行给出 N 个不重复的字符及其出现频率,格式如下:
c[1] f[1] c[2] f[2] … c[N] f[N]
其中c[i]是集合{‘0’ - ‘9’, ‘a’ - ‘z’, ‘A’ - ‘Z’, ‘_’}中的字符;f[i]是c[i]的出现频率,为不超过 1000 的整数。再下一行给出一个正整数 M(≤1000),随后是 M 套待检的编码。每套编码占 N 行,格式为:
c[i] code[i]
其中c[i]是第i个字符;code[i]是不超过63个’0’和’1’的非空字符串。
输出格式:
对每套待检编码,如果是正确的哈夫曼编码,就在一行中输出"Yes",否则输出"No"。
注意:最优编码并不一定通过哈夫曼算法得到。任何能压缩到最优长度的前缀编码都应被判为正确。
输入样例:
7
A 1 B 1 C 1 D 3 E 3 F 6 G 6
4
A 00000
B 00001
C 0001
D 001
E 01
F 10
G 11
A 01010
B 01011
C 0100
D 011
E 10
F 11
G 00
A 000
B 001
C 010
D 011
E 100
F 101
G 110
A 00000
B 00001
C 0001
D 001
E 00
F 10
G 11
输出样例:
Yes
Yes
No
No
代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
using namespace std;
int main(){
priority_queue<int,vector<int>,greater<int>>p;
map<string,string>mp2;
int n,m,f,a[101];
string c,code;
cin>>n;
for(int i=0;i<n;i++){
cin>>c>>f;
p.push(f);
a[i]=f;
}
int ans=0;
while(p.size()>=2){
int min1=p.top();
p.pop();
int min2=p.pop();
p.pop();
ans+=(min1+min2);
p.puah(min1+min2);
}
int ans1;
string str[101];
cin>>m;
for(int i=0;i<m;i++){
ans1=0;
for(int j=0;j<n;j++){
cin>>c>>code;
str[j]=code;
ans1+=code.size()*a[j];
}
if(ans1!=ans){
cout<<"No\n"<<endl;
}else{
int flag=1;
for(int j=0;j<n;j++){
for(int l=0;l<n;l++){
if(j!=l&&str[l].size()>=str[j].size()){
if(str[l].substr(0,str[j].size())==s2[j]){
flag=0;
break;
}
}
}
if(flag==0) break;
}
if(flag==1){
printf("Yes\n");
} else{
printf("No\n");
}
}
}
}
7-7 畅通工程之局部最小花费问题 (20 分)
#include<iostream>
using namespace std;
#define MAXN 110
#define INF 0xffffff
int AdjMatrix[MAXN][MAXN];
int lowcost[MAXN];
int closest[MAXN];
int sumCost=0;
void prim(int v,int n){
int mincost;
int k;
for(int i=1;i<=n;i++){
lowcost[i]=AdjMatrix[v][i];
closest[i]=v;
}
lowcost[v]=-1;
for(int i=0;i<n-1;i++){
mincost=INF;
for(int j=1;j<=n;j++){
if(lowcost[j]!=-1&&lowcost[j]<mincost){
mincost=lowcost[j];
k=j;
}
}
sumCost+=mincost;
lowcost[k]=-1;
for(int j = 1;j<=n;j++){
if(AdjMatrix[k][j]<lowcost[j]&&j!=k){
lowcost[j]=AdjMatrix[k][j];
closest[j]=k;
}
}
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<MAXN;i++){
for(int j = 0;j<MAXN;j++){
AdjMatrix[i][j]=INF;
}
}
for(int i=0;i<n*(n-1)/2;i++){
int x,y,cost,flag;
cin>>x>>y>>cost>>flag;
if(flag){
AdjMatrix[x][y]=AdjMatrix[y][x]=0;
}else{
AdjMatrix[x][y]=AdjMatrix[y][x]=cost;
}
}
prim(1,n);
cout<<sumCost<<endl;
return 0;
}
7-8 哈利·波特的考试 (20 分)
#include<iostream>
#include<cstring>
using namespace std;
#define MAXN 1010
int data[MAXN][MAXN];
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
data[i][j]=1000000000;
}
}
for(int i=0;i<=n;i++){
data[i][i]=0;
}
int a,b,c;
for(int i=0;i<m;i++){
cin>>a>>b>>c;
data[a][b]=data[b][a]=c;
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(data[i][j]>data[i][k]+data[k][j]){
data[i][j]=data[i][k]+data[k][j];
}
}
}
}
int maxx=1000000000;
int ans=-1;
for(int i=1;i<=n;i++){
int maxx1=-1;
for(int j=1;j<=n;j++){
if(data[i][j]>maxx1){
maxx1=data[i][j];
}
}
if(maxx1<maxx){
ans=i;
maxx=maxx1;
}
}
if(maxx==1000000000){
cout<<0;
}else{
cout<<ans<<" "<<maxx;
}
return 0;
}
7-9 整型关键字的散列映射 (20 分)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<stack>
#include<cstdio>
using namespace std;
#define MAXN 101000
int a[MAXN],b[MAXN],c[MAXN];
int main(){
int n,p,x,cnt=0;
cin>>n>>p;
for(int i=0;i<n;i++){
cin>>a[i];
}
memset(c,-1,sizeof(c));
for(int i=0;i<n;i++){
x=a[i];
if(c[a[i]]!=-1){
continue;
}
while(1){
if(b[x%p]==0){
b[x%p]=1;
c[a[i]]=x%p;
break;
}
x++;
}
}
cout<<c[a[0]];
for(int i=1;i<n;i++){
cout<<" "<<c[a[i]];
}
cout<<endl;
return 0;
}
7-10 PAT排名汇总 (20 分)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
#define MAXN 30010
typedef pair<string,int>pii;
vector<pii>v;
vector<pii>::iterator is;
//map<string,int>mp;
//map<string,int>::iterator it;
struct node{
int id;
string s;
int score;
int p;
}a[MAXN];
bool cmp1(node x,node y){
if(x.score==y.score){
return x.s<y.s;
}
return x.score>y.score;
}
bool cmp2(pii x,pii y){
if(x.second==y.second){
return x.first<y.first;
}
return x.second>y.second;
}
int main(){
int n,k,tscore,cnt=1;
cin>>n;
string ts;
int sum=1,temp=0,zongshu=0,paiming=1;
for(int i=1;i<=n;i++){
cin>>k;
v.clear();
paiming=1,temp=0,zongshu=0;
for(int j=0;j<k;j++){
cin>>ts>>tscore;
//mp[ts]=tscore;
v.push_back(make_pair(ts,tscore));//第一次正确代码的基础上去掉了map,用make_pair存在vector里代替map转vector
}
/*for(it=mp.begin();it!=mp.end();it++){
v.push_back(pii(it->first,it->second));
}*/
sort(v.begin(),v.end(),cmp2);
for(is=v.begin();is!=v.end();is++){
zongshu++;
a[cnt].id=i;
a[cnt].s=is->first;
a[cnt].score=is->second;
if(temp==is->second){
a[cnt].p=paiming;
}else{
a[cnt].p=zongshu;
paiming=zongshu;
}
temp=is->second;
cnt++;
}
}
int cnt1=1;
sort(a+1,a+cnt,cmp1);
cout<<cnt-1<<endl;
for(int i=1;i<cnt;i++){
cout<<a[i].s<<" ";
if(a[i].score==a[i-1].score){
cout<<cnt1<<" ";
}else{
cnt1=i;
cout<<i<<" ";
}
cout<<a[i].id<<" "<<a[i].p<<endl;
}
return 0;
}