上午写了一下删除链表中重复元素,不知道为什么输出不了结果
对循环链表进行元素的删除和增加,构建循环链表就是将链表的末指针指向头指针
题目描述
输入格式
输入:
第一行输入元素个数M
第二行输入M个元素
第三行输入删除位置,位置为0时不删除
第四行输入插入位置和插入元素
第五行输入输出时的起始位置
输出格式
样例输入content_copy
8
1 2 3 4 5 6 7 8
6
6 6
5
样例输出content_copy
5 6 7 8 1 2 3 4
#include<iostream>
using namespace std;
struct note
{
int date;
struct note *next;
};
int main()
{
struct note *head,*p,*q,*t;
int i,n,a;
scanf("%d",&n);
head=NULL;
for(i=0; i<n; i++)
{
scanf("%d",&a);
p=(struct note*)malloc(sizeof(struct note));
p->date=a;
p->next=NULL;
if(head==NULL)
head=p;
else
{
q->next=p;
}
q=p;
}
p->next=head;//设置循环链表,将末尾指针指向头指针
int k=1,s;
scanf("%d",&s);
t=head;
while(t!=NULL)
{
if(s==1)
{
head=t->next;//删除头指针的方法将头指针指向的指针作为新的头指针
break;
}
k++;
if(k==s)
{
t->next=t->next->next;
break;
}
t=t->next;
}
int j=1,d,f;
scanf("%d%d",&d,&f);
t=head;
while(t!=NULL)
{
if(d==1)
{
p=(struct note*)malloc(sizeof(struct note));
p->date=f;
p->next=head;
head=p;
break;
}
j++;
if(j==d)
{
p=(struct note*)malloc(sizeof(struct note));
p->date=f;
p->next=t->next;
t->next=p;
break;
}
t=t->next;
}
int g,l=0;
scanf("%d",&g);
t=head;
while(t->next!=head)
{
l++;
if(l==g
{
head=t;//将l位置的指针作为头指针
break;
}
t=t->next;
}
t=head;
while(t->next!=head)
{
printf("%d ",t->date);
t=t->next;
}
printf("%d",t->date);
return 0;
}
下午写了八皇后的题目
解题思路:从每一行的头开始遍历,每次判断该点是否符合放置条件,如果不满足就进入下一列(如果一行都不满足就返回-1,回到上一行往后遍历),如果满足就进入下一行,如果每一行都遍历完了,就返回0;开始提交代码时,有一个不能AC,时间超限,后面看到网上说用o2优化思路就AC了
题目描述
一个如下的 6 \times 66×6 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
上面的布局可以用序列 2\ 4\ 6\ 1\ 3\ 52 4 6 1 3 5 来描述,第 ii 个数字表示在第 ii 行的相应位置有一个棋子,如下:
行号 1\ 2\ 3\ 4\ 5\ 61 2 3 4 5 6
列号 2\ 4\ 6\ 1\ 3\ 52 4 6 1 3 5
这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。
并把它们以上面的序列方法输出,解按字典顺序排列。
请输出前 33 个解。最后一行是解的总个数。
输入格式
一行一个正整数 nn,表示棋盘是 n \times nn×n 大小的。
输出格式
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
输入输出样例
输入 #1复制
6
输出 #1复制
2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4
说明/提示
【数据范围】
对于 100\%100% 的数据,6 \le n \le 136≤n≤13。
题目翻译来自NOCOW。
USACO Training Section 1.5
#include<iostream>
using namespace std;
int a[20],n,m,num=0;
int book(int a[],int n)//传入要判断的点,n表示行,a[]表示列
{
int i;
for(i=1; i<n; i++)
{
if(abs(a[n]-a[i])==n-i||a[n]==a[i])//判断该位置的向下斜方向、向上斜方向以及同一列是否有王后
return -1;
}
return 0;
}
void dfs(int m)
{
if(m>n)//如果王后能放完n行,则得出了解
{
if(num<3)
{
for(int j=1; j<=n; j++)
{
printf("%d ",a[j]);
}
printf("\n");
}
num++;
}
else
{
for(int i=1; i<=n; i++)
{
a[m]=i;//m表示第m行,i表示第i列
if(book(a,m)==0)//如果该行能放置王后
dfs(m+1);
}
}
}
int main()
{
scanf("%d",&n);
dfs(1);
printf("%d",num);
}
刚开始的时候不是这样写的,就和迷宫题一样做标记,就从放置的第一个王后开始,将该王后所能限制的不能移动的方格做上标记,再将下一个王后放置在未被限制的方格中,又做一次标记,如果有一行全部被标记,就返回上一行,将王后移到未被标记的后一个方格中,直到全部遍历完。后面发现取消标记比较麻烦,而且时间复杂度较高
看了bfs,看懂了,代码还是不会写
明日计划
继续研究bfs和删除链表中重复元素