1月12日学习总结

上午写了一下删除链表中重复元素,不知道为什么输出不了结果

对循环链表进行元素的删除和增加,构建循环链表就是将链表的末指针指向头指针

题目描述

构建一个双向链表并进行删除和插入操作,按要求输出。

输入格式

 

输入:

第一行输入元素个数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和删除链表中重复元素

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值