信息学奥赛一本通(C++版)determination

第一部分 C++语言

第八章 指针

前缀和数组

【题目描述】
动态数组,计算前缀和数组。b是数组a的前缀和的数组定义:b[i]=a[0]+a[1]+a[2]+…+a[i],即b[i]是a的i个元素的和。

【我的代码】

#include<iostream>
using namespace std;
int main()
{
int n;
int *a;
cin>>n;
a=new int[n+1];//向操作系统申请了连续的n+1个int型的空间
for(int i=1;i<=n;i++)
	cin>>a[i];
for(int i=2;i<=n;i++)
	a[i]+=a[i-1];
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
delete[] a;
system("pause");
return 0;
}

行列转换问题

【问题描述】
矩阵可以认为是N*M的二维数组。现在有一个巨大但稀疏的矩阵。
N,M的范围是:1<=N ,M <=100000,有k个位置有数据,K的范围是:1<=K<=100000.
矩阵输入的方式是从上到下(第1行到第N行)、从左到右(从第一列到第M列)扫描,记录有数据坐标的位置(x,y)和值(v)。这是按照行优先的顺序保存数据的。现在要求按照列优先的方式输出数据,即从左到右、从上到下扫描,输出有数据的坐标和数值。

【输入格式】
第1行,3个整数N,M,K,其中1<=N,M,K<=100000;下面有K行,每行3个整数;a,b,c,表示第a行第b列有数据c。数据在int范围内,保证是行优先的次序。

【输出格式】
1行,K个整数,是按照列优先次序输出的数
【参考代码】

#include<iostream>
using namespace std;
int main()
{
const int LP=100001;
int n,m,k;
int x[LP],y[LP],d[LP];
int c[LP];//每列的数据个数
int *a[LP];//每列一个指针
cin>>n>>m>>k;
memset(c,0,sizeof(c));
for(int i=1;i<=k;i++)
{
cin>>x[i]>>y[i]>>d[i];//x[i]和y[i]是第i个数据所在行号和列号
c[y[i]]++;//统计c数组中每列的数据个数
}
for(int i=1;i<=m;i++)
	a[i]=new int[c[i]];//第i列指针申请数组空间
for(int i=1;i<=k;i++)
{
*a[y[i]]=d[i];//数据放在相应列的数组中
a[y[i]]++;//数组指针移到下一个位置
}
for(int i=1;i<=m;i++)//按照列优先次序输出
{
a[i]-=c[i];//指针回到每列的前面
for(int j=1;j<=c[i];j++,a[i]++)
	cout<<*a[i]<<" ";
}
system("pause");
return 0;
}

约瑟夫环问题(循环链表应用)

【问题描述】
有 M 个人,其编号分别为 1-M。这 M 个人按顺序排成一个圈(如图)。现在给定一个数 N,从第一个人开始依次报数,数到 N 的人出列,然后又从下一个人开始又从 1 开始依次报数,数到 N 的人又出列...如此循环,直到最后一个人出列为止。

【输入格式】​
输入只有一行,包括 2 个整数 M,N。之间用一个空格分开(0 < n <= m <= 100)。

【输出格式】
​ 输出只有一行,包括 M 个整数

【样列输入】

8 5

【样列输出】

5 2 8 7 1 4 6 3

【参考代码】

#include<iostream>
using namespace std;
struct node{
long d;
node *next;
};
node *head,*p,*r;
long n,m;
int main()
{
	cin>>n>>m;
	while(n!=0&&m!=0)
	{
	head=new node;
	head->d=1;
	head->next=NULL;
	r=head;
	for(int i=2;i<=n;i++)
	{
	p=new node;
	p->d=i;
	p->next=NULL;
	r->next=p;
	r=p;
	}
	r->next=head;
	r=head;
	for(int i=1;i<n;i++)
	{
		for(int j=1;j<=m-2;j++)r=r->next;
		r->next=r->next->next;
		r=r->next;
	}
	cout<<r->d<<endl;
	cin>>m>>n;
	}
	system("pause");
return 0;
}

删除数组中的元素(链表)

【题目描述】
给定N个整数,将这些整数中与M相等的删除。
假定给出的整数序列为:1,3,3,0,-3,5,6,8,3,10,22,-1,3,5,11,20,100,3,9,3。
应该将其放在一个链表中,链表长度为20。
要删除的数是3,删除以后,链表中只剩14个元素:1 0 -3 5 6 8 10 22 -1 5 11 20 100 9
要求:必须使用链表,不允许使用数组,也不允许不删除元素直接输出。
程序中必须有链表的相关操作:建立链表,删除元素,输出删除后链表中元素,释放链表。

【输入格式】
输入包含3行:
第一行是一个整数n(1 <= n <= 200000),代表数组中元素的个数。
第二行包含n个整数,代表数组中的n个元素。每个整数之间用空格分隔;每个整数的取值在32位有符号整数范围以内。
第三行是一个整数k,代表待删除元素的值(k的取值也在32位有符号整数范围内)。

【输出格式】
输出只有1行:将数组内所有待删除元素删除以后,输出数组内的剩余元素的值,每个整数之间用空格分隔。

【样例输入】

20
1 3 3 0 -3 5 6 8 3 10 22 -1 3 5 11 20 100 3 9 3
3

【样例输出】

1 0 -3 5 6 8 10 22 -1 5 11 20 100 9

【我的代码】

#include<iostream>
using namespace std;
struct node {
int d;
node *next;
};
node *head,*p,*r;
int n,x;
int main()
{
cin>>n;
head= new node;
r=head;
for(int i=1;i<=n;i++)
{
	cin>>x;
	p=new node;
	p->next=NULL;
	p->d=x;
	r->next=p;
	r=p;
}
p=head;
int x;
cin>>x;
while(p!=NULL)
{
	r=p->next;
	if(r&&r->d==x){p->next=p->next->next;free(r);}
	else p=p->next;//else 很重要
}
r=head->next;
while(r->next!=NULL)
{
cout<<r->d<<" ";
r=r->next;
}
cout<<r->d<<endl;
system("pause");
return 0;
}

统计学生信息(使用动态链表完成)

【题目描述】
利用动态链表记录从标准输入输入的学生信息(学号、姓名、性别、年龄、得分、地址)。其中,学号长度不超过20, 姓名长度不超过40, 性别长度为1, 地址长度不超过40。

【输入格式】
包括若干行,每一行都是一个学生的信息,如:
00630018 zhouyan m 20 10.0 28#460
输入的最后以"end"结束。

【输出格式】
将输入的内容倒序输出。每行一条记录,按照下面的格式输出:
学号 姓名 性别 年龄 得分 地址

【样例输入】

00630018 zhouyan m 20 10 28#4600
0063001 zhouyn f 21 100 28#460000
0063008 zhoyan f 20 1000 28#460000
0063018 zhouan m 21 10000 28#4600000
00613018 zhuyan m 20 100 28#4600
00160018 zouyan f 21 100 28#4600
01030018 houyan m 20 10 28#4600
0630018 zuyan m 21 100 28#4600
10630018 zouan m 20 10 28#46000
end

【样例输出】

10630018 zouan m 20 10 28#46000
0630018 zuyan m 21 100 28#4600
01030018 houyan m 20 10 28#4600
00160018 zouyan f 21 100 28#4600
00613018 zhuyan m 20 100 28#4600
0063018 zhouan m 21 10000 28#4600000
0063008 zhoyan f 20 1000 28#460000
0063001 zhouyn f 21 100 28#460000
00630018 zhouyan m 20 10 28#4600

【我的代码】

#include<iostream>
using namespace std;
struct node{
char num[20];
char name[40];
char sex;
int age;
int score;
char add[40];
node *pre,*next;
};
node *head,*p,*r;
int main()
{
head= new node;
head->next=NULL;
head->pre=NULL;
r=head;
while(1)
{
p=new node;
cin>>p->num;
if(strcmp(p->num,"end")==0)break;
cin>>p->name>>p->sex>>p->age>>p->score>>p->add;
p->pre=r;
r->next=p;
p->next=NULL;
r=p;
}
p=r;
while(p->pre!=NULL)//p->pre
{
cout<<p->num<<" "<<p->name<<" "<<p->sex<<" "<<p->age<<" "<<p->score<<" "<<p->add<<endl;
p=p->pre;
}
system("pause");
return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值