- 窗口问题
【问题描述】
在某图形操作系统中,有N个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。
当你点击屏幕上一个点的时候,你就选择了处于被点击位置的最顶层窗口,并且这个窗口就会被移到所有窗口的最顶层,而剩余的窗口的层次顺序不变。如果你点击的位置不属于任何窗口,则系统会忽略你这次点击。
现在我们希望你写一个程序模拟点击窗口的过程。
【输入形式】
输入的第一行有两个正整数,即N和M。(1≤N≤10,1≤M≤10)接下来N行按照从最下层到最顶层的顺序给出N个窗口的位置。每行包含四个非负整数x1,y1,x2,y2,表示该窗口的一对顶点坐标分别为(x1,y1)和(x2,y2)。保证x1<x2,y1<y2。
接下来M行每行包含两个非负整数x,y,表示一次鼠标点击的坐标。题目中涉及到的所有点和矩形的顶点的x,y坐标分别不超过2559和1439。
【输出形式】
输出包括M行,每一行表示一次鼠标点击的结果。如果该次鼠标点击选择了一个窗口,则输出这个窗口的编号(窗口按照输入中的顺序从1编号到N);如果没有,则输出"IGNORED"(不含双引号)。
【样例输入】
3 4
0 0 4 4
1 1 5 5
2 2 6 6
1 1
0 0
4 4
0 5
【样例输出】
2
1
1
IGNORED
【样例说明】
第一次点击的位置同时属于第1和第2个窗口,但是由于第2个窗口在上面,它被选择并且被置于顶层。
第二次点击的位置只属于第1个窗口,因此该次点击选择了此窗口并将其置于顶层。现在的三个窗口的层次关系与初始状态恰好相反了。第三次点击的位置同时属于三个窗口的范围,但是由于现在第1个窗口处于顶层,它被选择。
最后点击的(0,5)不属于任何窗口。
//我自己还添加了一些链表的其他算法,已经注释掉了,测试点都可以过。
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct
{
int x1,y1;
int x2,y2;
int tag;
}LinkWindow;
typedef struct LNode
{
LinkWindow data;
struct LNode *next;
}LinkList;
LinkList *L;
int n,m;
void CreateListF(LinkList *&L)
{
LinkList *s;
int i;
for(i=0;i<n;i++)
{
s=(LinkList *)malloc(sizeof(LinkList));
cin>>s->data.x1>>s->data.y1>>s->data.x2>>s->data.y2;
s->data.tag=i+1;
s->next=L->next;
L->next=s;
}
}
void InitList(LinkList *&L)
{
L=(LinkList *)malloc(sizeof(LinkList));
L->next=NULL;
}
void DestroyList(LinkList *&L)
{
LinkList *pre=L,*p=L->next;
while(p!=NULL)
{
free(pre);
pre=p;
p=pre->next;
}
free(pre);
}
bool ListEmpty(LinkList *L)
{
return (L->next==NULL);
}
int ListLength(LinkList *L)
{
int t=0;
LinkList *p=L;
while(p->next!=NULL)
{
t++;
p=p->next;
}
return (t);
}
void DispList(LinkList *L)
{
LinkList *p=L->next;
while(p!=NULL)
{
cout<<p->data.tag<<" "<<"("<<p->data.x1<<","<<p->data.y1<<")"<<" "<<"("<<p->data.x2<<","<<p->data.y2<<")"<<endl;
p=p->next;
}
cout<<endl;
}
bool GetElem(LinkList *L,int i,LinkWindow &e)
{
int j=0;
LinkList *p=L;
while(j<i&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL)
return false;
else
{
e=p->data;
return true;
}
}
bool noequal(LinkList *p,LinkWindow e)
{
if((p->data.x1!=e.x1)||(p->data.y1!=e.y1)||(p->data.x2!=e.x2)||(p->data.y2!=e.y2))
return true;
else return false;
}
int LocateElem(LinkList *L,LinkWindow e)
{
int i=1;
LinkList *p=L->next;
while(p!=NULL&&noequal(p,e))
{
p=p->next;
i++;
}
if(p==NULL) return (0);
else return (i);
}
bool ListInsert(LinkList *&L,int i,LinkWindow e)
{
int j=0;
LinkList *p=L,*s;
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL) return false;
else
{
s=(LinkList *)malloc(sizeof(LinkList));
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
}
bool ListDelete(LinkList *&L,int i,LinkWindow &e)
{
int j=0;
LinkList *p=L,*q;
while(j<i-1&&p!=NULL)
{
j++;
p=p->next;
}
if(p==NULL) return false;
else
{
q=p->next;
if(q==NULL) return false;
e=q->data;
p->next=q->next;
free(q);
return true;
}
}
void DisWindow(LinkWindow e)
{
cout<<e.tag<<" "<<"("<<e.x1<<","<<e.y1<<")"<<" "<<"("<<e.x2<<","<<e.y2<<")"<<endl;
}
void Click(LinkList *&L)
{
int i;
LinkList *p=L->next;
LinkWindow e;
for(i=0;i<m;i++)
{
p=L->next;
int x,y,t;
cin>>x>>y;
while(p!=NULL)
{
if((x>=p->data.x1)&&(x<=p->data.x2)&&(y>=p->data.y1)&&(y<=p->data.y2))
break;
p=p->next;
}
if(p==NULL) cout<<"IGNORED"<<endl;
else if(p!=L->next)
{
e=p->data;
t=LocateElem(L,e);
if(ListDelete(L,t,e))
{
if(ListInsert(L,1,e))
cout<<e.tag<<endl;
}
}
else if(p==L->next)
{
cout<<p->data.tag<<endl;
}
}
}
int main()
{
LinkWindow e;
cin>>n>>m;
InitList(L);
CreateListF(L);
Click(L);
return 0;
}
- 约瑟夫(Joseph)问题
【问题描述】
约瑟夫(Joseph)问题的一种描述是:编号为1,2,3,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码〈正整数〉,一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
基本要求:利用单向循环链表存储结构模拟此过程,按照出列的顺序打印出各人的编号。
实现提示:程序运行后首先要求用户指定初始报数上限值,然后读取各人的密码(小于30)。
【输入形式】
输入包括两行,第一行包括报数上限值m和人数n,第二行为n个人的密码,所有数据之间由空格分隔。
【输出形式】
输出一行,共n个整数,表示各编号人的出列顺序。各数之间由空格分隔。
【样例输入】
20 7
3 1 7 2 4 8 4
【样例输出】
6 1 4 7 2 3 5
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct LNode
{
int data;
int tag;
struct LNode *next;
}LinkList;
LinkList *L;
int m,n;
void CreateListF(LinkList *&L)
{
LinkList *s,*r;
int i;
r=L;
for(i=0;i<n;i++)
{
s=(LinkList *)malloc(sizeof(LinkList));
cin>>s->data;
s->tag=i+1;
r->next=s;
r=s;
}
r->next=L;
}
void InitList(LinkList *&L)
{
L=(LinkList *)malloc(sizeof(LinkList));
L->next=L;
}
void DestroyList(LinkList *&L)
{
LinkList *pre=L,*p=L->next;
while(p!=L)
{
free(pre);
pre=p;
p=pre->next;
}
free(pre);
}
bool ListEmpty(LinkList *L)
{
return (L->next==L);
}
int ListLength(LinkList *L)
{
int t=0;
LinkList *p=L;
while(p->next!=L)
{
t++;
p=p->next;
}
return (t);
}
void DispList(LinkList *L)
{
LinkList *p=L->next;
while(p!=L)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
bool GetElem(LinkList *L,int i,int &e)
{
int j=1;
LinkList *p=L->next;
while(j<i&&p!=L)
{
j++;
p=p->next;
}
if(p==L)
return false;
else
{
e=p->data;
return true;
}
}
int LocateElem(LinkList *L,int e)
{
int i=1;
LinkList *p=L->next;
while(p!=L&&p->data!=e)
{
p=p->next;
i++;
}
if(p==L) return (0);
else return (i);
}
bool ListInsert(LinkList *&L,int i,int e)
{
int j=0;
LinkList *p=L,*s;
if(i==1)
{
s=(LinkList *)malloc(sizeof(LinkList));
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
else
{
p=L->next;
while(j<i-1&&p!=L)
{
j++;
p=p->next;
}
if(p==L) return false;
else
{
s=(LinkList *)malloc(sizeof(LinkList));
s->data=e;
s->next=p->next;
p->next=s;
return true;
}
}
}
bool ListDelete(LinkList *&L,int i,int &e)
{
int j=1;
LinkList *p=L,*q;
if(i==1)
{
q=L->next;
e=q->data;
L->next=q->next;
free(q);
return true;
}
else
{
p=L->next;
while(j<i-1&&p!=L)
{
j++;
p=p->next;
}
if(p==L) return false;
else
{
q=p->next;
if(q==L) return false;
e=q->data;
p->next=q->next;
free(q);
return true;
}
}
}
void OutList(LinkList *&L)
{
LinkList *p=L->next,*q;
int i=1,e;
while(1)
{
while(i<m)
{
if(p->next==L) p=L->next;
else p=p->next;
i++;
}
cout<<p->tag<<" ";
if(p->next==L) q=L->next;
else q=p->next;
int t=1;
LinkList *s=L->next;
while(s!=p)
{
s=s->next;
t++;
}
if(ListDelete(L,t,e)) m=e;
p=q;
i=1;
if(ListLength(L)==0) break;
}
cout<<endl;
}
int main()
{
int e,t;
cin>>m>>n;
InitList(L);
CreateListF(L);
OutList(L);
return 0;
}