给定一个带整数键值的单链表L,本题要求你编写程序,删除那些键值的绝对值有重复的结点。即对任意键值K,只有键值或其绝对值等于K的第一个结点可以被保留。同时,所有被删除的结点必须被保存在另外一个链表中。例如:另L为21→-15→-15→-7→15,则你必须输出去重后的链表21→-15→-7、以及被删除的链表-15→15。
输入格式:
输入第一行包含链表第一个结点的地址、以及结点个数N(<= 105 的正整数)。结点地址是一个非负的5位整数,NULL指针用-1表示。
随后N行,每行按下列格式给出一个结点的信息:
Address Key Next
其中Address是结点的地址,Key是绝对值不超过104的整数,Next是下一个结点的地址。
输出格式:
首先输出去重后的链表,然后输出被删除结点组成的链表。每个结点占一行,按输入的格式输出。
输入样例:
00100 5
99999 -7 87654
23854 -15 00000
87654 15 -1
00000 -15 99999
00100 21 23854
输出样例:
00100 21 23854
23854 -15 99999
99999 -7 -1
00000 -15 87654
87654 15 -1
#include
#include
#include
#include
#include
using namespace std;
struct Node
{
int key,next;
};
///b数组用来记录被删除的节点的地址
int main()
{
int a0,n,b[100005],ans,m;
int vis[10005];
int add,k,Next;
Node a[100005];
memset(vis,0,sizeof(vis));
cin>>a0>>n;
for(int i=0;icin>>add>>k>>Next;
a[add].key=k;
a[add].next=Next;
}
m=a0;
ans=abs(a[m].key);
printf("%05d %d",a0,a[m].key);
vis[ans]=1;
int t=0;
while(1)
{
m=a[m].next;
if(m==-1)
{
cout<<" -1"<break;
}
ans=abs(a[m].key);
if(vis[ans]==0){
printf(" %05d\n%05d %d",m,m,a[m].key);
vis[ans]=1;
}
else
{
b[t++]=m;
}
}
if(t>0)
{
printf("%05d %d",b[0],a[b[0]].key);
for(int i=1;iprintf(" %05d\n%05d %d",b[i],b[i],a[b[i]].key);
}
cout<<" -1"<return 0;
}
L2-013. 红色警报
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报。
输入格式:
输入在第一行给出两个整数N(0 < N <=500)和M(<=5000),分别为城市个数(于是默认城市从0到N-1编号)和连接两城市的通路条数。随后M行,每行给出一条通路所连接的两个城市的编号,其间以1个空格分隔。在城市信息之后给出被攻占的信息,即一个正整数K和随后的K个被攻占的城市的编号。
注意:输入保证给出的被攻占的城市编号都是合法的且无重复,但并不保证给出的通路没有重复。
输出格式:
对每个被攻占的城市,如果它会改变整个国家的连通性,则输出“Red Alert: City k is lost!”,其中k是该城市的编号;否则只输出“City k is lost.”即可。如果该国失去了最后一个城市,则增加一行输出“Game Over.”。
输入样例:
5 4
0 1
1 3
3 0
0 4
5
1 2 0 4 3
输出样例:
City 1 is lost.
City 2 is lost.
Red Alert: City 0 is lost!
City 4 is lost.
City 3 is lost.
Game Over.
#include
using namespace std;
int Map[510][510],vis[510],n,m,k;
vector<int> V[510];
void dfs(int node)
{
vis[node] = 1;
for(int i=0;iif(vis[i] == 0 &&Map[node][i] == 1){
dfs(i);
}
}
}
int countnum()
{
int cnt = 0;//初始值为0
memset(vis,0,sizeof(vis));
for(int i=0;iif(vis[i] == 0){/*只要有城市没有被访问过就递归搜索与这个城市连接的所有城市*/
dfs(i);
cnt++;
}
}
return cnt;
}
int main()
{
int m,k,x,y;
memset(Map,0,sizeof(Map));
cin>>n>>m;
for(int i=0;i//输入图
cin>>x>>y;
Map[x][y] = Map[y][x] = 1;
}
int cnt = countnum();//计算有多少个联通量
cin>>k;
for(int i=0;icin>>x;
for(int j=0;jif(Map[x][j] == 1){
Map[x][j] = Map[j][x] = 0;
}
}
int tempcnt = countnum();
if(tempcnt>cnt+1)
printf("Red Alert: City %d is lost!\n",x);
else
printf("City %d is lost.\n",x);
cnt = tempcnt;
if(i == n-1){
printf("Game Over.\n");
}
}
return 0;
}
L2-004. 这是二叉搜索树吗?
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点,
其左子树中所有结点的键值小于该结点的键值;
其右子树中所有结点的键值大于等于该结点的键值;
其左右子树都是二叉搜索树。
所谓二叉搜索树的“镜像”,即将所有结点的左右子树对换位置后所得到的树。
给定一个整数键值序列,现请你编写程序,判断这是否是对一棵二叉搜索树或其镜像进行前序遍历的结果。
输入格式:
输入的第一行给出正整数N(<=1000)。随后一行给出N个整数键值,其间以空格分隔。
输出格式:
如果输入序列是对一棵二叉搜索树或其镜像进行前序遍历的结果,则首先在一行中输出“YES”,然后在下一行输出该树后序遍历的结果。数字间有1个空格,一行的首尾不得有多余空格。若答案是否,则输出“NO”。
输入样例1:
7
8 6 5 7 10 8 11
输出样例1:
YES
5 7 6 8 11 10 8
输入样例2:
7
8 10 11 8 6 7 5
输出样例2:
YES
11 8 10 7 5 6 8
输入样例3:
7
8 6 8 5 10 9 11
输出样例3:
NO
#include
#include
#include
#include
#include
#include
using namespace std;
struct BSTNode
{
int key;
struct BSTNode *lchild,*rchild;
};
int Inetrt(BSTNode *&p,int k)
{
if(p==NULL)
{
p=(BSTNode*)malloc(sizeof(BSTNode));
p->key=k;
p->lchild=p->rchild=NULL;
return 1;
}
else if(kkey)
return Inetrt(p->lchild,k);
else
return Inetrt(p->rchild,k);
}
BSTNode *CreateBST(int a[],int n)
{
BSTNode *bt=NULL;
int i=0;
while(ireturn bt;
}
int Inetrt1(BSTNode *&p,int k)
{
if(p==NULL)
{
p=(BSTNode*)malloc(sizeof(BSTNode));
p->key=k;
p->lchild=p->rchild=NULL;
return 1;
}
else if(kkey)
return Inetrt1(p->rchild,k);
else
return Inetrt1(p->lchild,k);
}
BSTNode *CreateBST1(int a[],int n)
{
BSTNode *bt1=NULL;
int i=0;
while(ireturn bt1;
}
int c[1005],tt;
void PostOrder(BSTNode *bt)
{
if(bt!=NULL)
{
PostOrder(bt->lchild);
PostOrder(bt->rchild);
c[tt++]=bt->key;
}
}
int b[1005],t;
void PreOrder(BSTNode *bt)
{
if(bt!=NULL)
{
//printf("%d ",bt->key);
b[t++]=bt->key;
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
}
int main()
{
int n,a[1005],ans=1;
BSTNode *bt,*bt1;
t=0;tt=0;
cin>>n;
for(int i=0;icin>>a[i];
bt=CreateBST(a,n);
PreOrder(bt);
for(int i=0;iif(a[i]!=b[i])
ans=0;
}
if(ans==1)
{
cout<<"YES"<cout<0];
for(int i=1;icout<<" "<cout<if(ans==0)
{
ans=1;t=0;
bt1=CreateBST1(a,n);
PreOrder(bt1);
for(int i=0;iif(a[i]!=b[i])
ans=0;
if(ans==1)
{
cout<<"YES"<0;
PostOrder(bt1);
//cout<
for(int i=0;iif (i==0)
cout<else
cout<<" "<cout<if(ans==0)
cout<<"NO"<return 0;
}
L2-011. 玩转二叉树
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
1 2 3 4 5 6 7
4 1 3 2 6 5 7
输出样例:
4 6 1 7 5 3 2
#include
#include
#include
#include
#include
using namespace std;
struct BTNode
{
int key;
struct BTNode *lchild,*rchild;
};
BTNode *CreateBTN(int x[],int z[],int n)
{
BTNode *b;
b=(BTNode*)malloc(sizeof(BTNode));
int t,i,k,temp1[35],temp2[35],temp3[35];
if(n<=0)
return NULL;
t=x[0];
b->key=t;
for(i=0;iif(t==z[i])
break;
k=0;
for(int j=1;j1;j++)
temp1[k++]=x[j];
b->lchild=CreateBTN(temp1,z,i);
k=0;
for(int j=i+1;jint kk=0;
for(int j=i+1;jrchild=CreateBTN(temp2,temp3,n-i-1);
return b;
}
void Exchange(BTNode *&b)
{
BTNode *p;
if(b)
{
p=b->lchild;
b->lchild=b->rchild;
b->rchild=p;
Exchange(b->lchild);
Exchange(b->rchild);
}
}
int a[35],tt;
void LevelOrder(BTNode *b)
{
queue Q;
BTNode *p;
Q.push(b);
while(!Q.empty())
{
p=Q.front();
a[tt++]=p->key;
Q.pop();
if(p->lchild)
Q.push(p->lchild);
if(p->rchild)
Q.push(p->rchild);
}
}
int main()
{
int n,z[35],x[35];
tt=0;
BTNode *b;
cin>>n;
for(int i=0;icin>>z[i];
for(int i=0;icin>>x[i];
b=CreateBTN(x,z,n);
Exchange(b);
LevelOrder(b);
cout<0];
for(int i=1;icout<<" "<cout<return 0;
}