链表去重
给定一个键值为整数的单链表 L,将键值的绝对值有重复的结点删除:即对任意键值K,只有键值或其绝对值等于 K 的第一个结点被保留在 L 中。例如,下面单链表L 包含键值21、-15、15、7、-15;去重后的链表 L 包含键值 21、-15、7。
输入说明: 输入的第一行包含两个整数,分别表示链表第一个结点的地址和结点个数n(1≤n≤100)。结点地址是一个非负的 5 位整数,NULL 指针用-1 表示。 随后 n 行,每行含 3 个整数,按下列格式给出一个结点的信息: Address Key Next 其中 Address 是结点的地址,Key 是绝对值不超过 10000 的整数,Next 是下一个结点的地址。输出说明: 输出的第一行为去重后链表 L 的长度,换行;接下来按顺序输出 L 的所有结点,每个结点占一行,按照 Address Key Next 的格式输出,间隔 1 个空格。
1 指针赋地址就是强制转换
2 注意输出格式,0补齐。
很久很久之前写的…………只有60分。
#include<stdio.h>
int main()
{
int node[100000][2] = { 0 };
int head = 0, num = 0;
int count = 0, i, k;
scanf("%d%d", &head, &num);
for (i = 0; i < num; i++)
{
scanf("%d", &k);
scanf("%d%d", &node[k][0], &node[k][1]);//address, value and next
}
for (i = head; node[i][1] != -1&&count<num; i = node[i][1])
{
if (node[i][0])
{
count++;
for (k = node[i][1]; node[k][1] != -1; k = node[k][1])
{
if (node[i][0] == node[k][0] || node[i][0] == -1 * node[k][0])
node[k][0] = 0;
}
}
}
printf("%d\n", count); //print
printf("%05d %d ", head, node[head][0]);
for (i = node[head][1]; node[i][1] != -1; i = node[i][1])
{
if ( node[i][0])
printf("%05d\n%05d %d ", i, i, node[i][0]);
}
printf("-1\n");
return 0;
}
报数出列问题
已知N个人(以编号1,2,3,...,N分别表示)排成一列, 第一轮从编号为1的人开始依次报数,数到2的倍数的人出列;第二轮从头开始依次报数,数到3的倍数的人出列;第三轮再次从头开始依次报数,数到2的倍数的人出列;第四轮从头开始依次报数,数到3的倍数的人出列;依此规律重复下去,直到队列中的人数不超过三个为止。要求输出此时队列中剩下的人在初始队列中的编号。
使用队列,每次操作时对队列中元素进行判断,不需要舍弃的就重新加入队列;
但是实际上对于一道题而言,用队列很麻烦
#include <iostream>
using namespace std;
int main() {
int k;
cin >> k;
int a[k + 1] = {0};
int sum = k;
int t;
for (int flag = 0; sum > 3; flag++) {//每执行一次这个循环,2倍数或3倍数的人出列
//flag为双数,2倍数出列;为奇数,3倍数出列
t = 0;
for (int i = 1; i <= k; i++) {//每进行一次这层循环,有0/1个人出列
if (a[i] == 0) {//数组值为0说明还没有出列,1说明出列了
t++;//t是队列剩余人数中,当前遍历到的人的编号
}
if (flag % 2 == 0 && t % 2 == 0 && a[i] == 0) {
a[i] = 1;
sum--;
} else if (flag % 2 == 1 && t % 3 == 0 && a[i] == 0) {
a[i] = 1;
sum--;
}
}
}
for (int i = 1; i <= k; i++) {
if (a[i] == 0)
cout << i << " ";
}
return 0;
}
奇偶序列
输入一个整数组成的序列,然后将序列中的奇数位置结点依序放在前面,偶数位置结点依序放在后面,组成一个新的序列。输出此新序列。
#include<stdio.h>
int main()
{
int n;scanf("%d",&n);
int even[100]={0},odd[100]={0};
int e=0,o=0;
for(int i=1;i<=n;i++)
{
if(i%2){
scanf("%d",&odd[o]);o++;
}
else {
scanf("%d",&even[e]);e++;
}
}
for(int i=0;i<o;i++)
printf("%d ",odd[i]);
for(int i=0;i<e;i++)
printf("%d ",even[i]);
return 1;
}
有序表的合并去重
已知两个有序线性表L1和L2,每个线性表中数据元素的值为单调增的正整数(<100个),各线性表内部无重复元素。把L2中的元素合并到L1中,要求L1中数据元素的值仍为单调递增,且无重复元素。
#include<stdio.h>
int main()
{
int n1,n2;scanf("%d%d",&n1,&n2);
int a[200]={0};
for(int i=0;i<(n1+n2);i++)
scanf("%d",&a[i]);
//起泡排序
int flog,i,j,t;
for(i=0;i<(n1+n2);i++)
{
flog=1;
for(j=n1+n2-1;j>i;j--)
{
if(a[j-1]>a[j])
{
t=a[j];a[j]=a[j-1];a[j-1]=t;
flog=0;
}
}
if(flog)
break;
}
printf("%d ",a[0]);
for(i=1;i<(n1+n2);i++)
{
if(a[i]==a[i-1])
continue;
else printf("%d ",a[i]);
}
return 1;
}
最小周期串
如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期。例如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。输入一个长度不超过80的串,输出它的最小周期。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char str[100]={0};
scanf("%s",str);
int len=strlen(str);//长度
for(int i=1;i<=len;i++)//从小到大逐个尝试最小周期
{//注意一点i要取等号
int flog=1;
for(int j=i;flog&&j<len;j++)
{//直接求周期不好求,方法就是穷举
if(str[j]!=str[j-i])
flog=0;
}
if(flog)
{
printf("%d",i);return 0;
}
}
}
顺寻串的next函数
next函数就是:管你理解不理解,背过就完事了
void get_next(char str[],int next){
i=1;next[1]=0;j=0;
while(i<str[0]){
第0位记录长度
if(j==0||str[i]==str[j]){i++;j++;next[i]=j;}
else j=next[j]
}
}
判断栈序列
如果以序列“1,2,3,4”作为一个栈(初始为空)的输入,那么可得到输出序列“1,2,3,4”或“4,3,2,1”或“2,3,1,4”等等,但是肯定得不到输出序列“4,1,2,3”或“3,1,2,4”等等。请编写一个程序,判断能否通过一个栈得到给定的输出序列。
逐个入栈->如果栈顶和所给序列相同->出栈|||->如果栈顶和所给序列不同->继续入栈
#include<iostream>
#include<stack>
using namespace std;
int main()
{
int n;scanf("%d",&n);
int a[100]={0};
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
stack<int>b;
int j=0;
for(int i=1;i<=n;i++)
{
b.push(i);
while(j<n)
{
if(b.empty()) break;//一定一定一定要有这个
if(b.top()==a[j])
{
b.pop();
j++;
}
else break;
}
}
//yes:当遍历完原序列时,恰好stack也全部出栈了 。
//no:stack有无法出栈的。
if(b.empty())
printf("yes");
else
printf("no");
return 1;
}
后缀表达式、前缀表达式、括号匹配
数据结构题C语言:栈的练习_NI3E-CSDN博客_c语言栈题目
矩阵加法
看着花里胡哨,思路大概就是:输入的矩阵+数字转化成正常的矩阵,然后逐个相加并最后输出结果,结果也要改成花里胡哨的。
#include<stdio.h>
int main()
{
int row, col;
scanf_s("%d%d", &row, &col);
int a[100][100] = { 0 },b[100][100]={ 0 };
/*输入第一个矩阵*/
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
scanf_s("%d", &a[i][j]);
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
if (a[i][j])
scanf_s("%d", &a[i][j]);
}
/*输入第二个矩阵*/
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
scanf_s("%d", &b[i][j]);
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
if (b[i][j])
scanf_s("%d", &b[i][j]);
}
/*输出结果*/
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (a[i][j] + b[i][j])
printf("1 ");
else
printf("0 ");
}
printf("\n");
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
if (a[i][j] + b[i][j])
printf("%d ",a[i][j]+b[i][j]);
}
return 1;
}