基础数据结构
线性表和链表是其他数据结构的基础。
遇到题目先考虑这个题目要用什么样的数据结构来解题。
比较形象的想象这步操作会达到怎么样的理想的结果,如果不是想象中的结果就用调试来检查,然后修改。
1 链表
1.1 动态列表
洛谷P1996 约瑟夫问题
思路:循环链表,链表删除结点的操作(找到要删除结点的前一个结点)
代码:
#include<bits/stdc++.h>
typedef struct node{
int data;
struct node *next;
}LNode,*LinkList;
int main(){
int n,m;
scanf("%d%d",&n,&m);
LNode *head;
head = new LNode;
head->data=1;
head->next=NULL;
LNode *p,*now;
now=head;
for(int i=2;i<=n;i++){
p=new LNode;
p->data=i;
p->next=NULL;
now->next=p;
now=p;
}
now->next=head;
now=head;
LNode *prev;
prev=now;
while(n>0){
for(int i=1;i<=m-2;i++){
prev=prev->next;
}
LNode *q=prev->next;
printf("%d ",q->data);
prev->next=prev->next->next;
prev=q->next;
free(q);
n--;
}
return 0;
}
1.2 静态链表
用一维数组实现单向静态链表 洛谷P1996 约瑟夫问题
#include<bits/stdc++.h>
int people[105];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n-1;i++){
people[i]=i+1;
}
people[n]=1;
int now=1,prev=1;
while(n>0){
for(int i=1;i<=m-1;i++){
prev=now;
now=people[now];
}
printf("%d ",now);
n--;
people[prev]=people[now];
now=people[prev];
}
return 0;
}
2.3 双向链表
洛谷P1160 队列安排
60分有两个样例超时代码:
#include<bits/stdc++.h>
int hasht[100005]={0};
struct node{
int front;
int rear;
}node[100005];
int start=0;
int main(){
int n;
scanf("%d",&n);
node[0].front=-1;
node[0].rear=1;
node[1].front=0;
node[1].rear=-1;
hasht[1]=1;
for(int i=2;i<=n;i++){
int k,p;
scanf("%d%d",&k,&p);
if(p==0){
node[i].rear=k;
node[i].front=node[k].front;
node[node[k].front].rear=i;
node[k].front=i;
}else if(p==1){
node[i].rear=node[k].rear;
node[node[k].rear].front=i;
node[i].front=k;
node[k].rear=i;
}
hasht[i]=1;
}
int m;
scanf("%d",&m);
while(m--){
int del;
scanf("%d",&del);
for(int i=node[start].rear;i!=-1;i=node[i].rear){
if(i==del&&hasht[i]==1){
hasht[i]=0;
node[node[i].front].rear=node[i].rear;
node[node[i].rear].front=node[i].front;
}
else if(hasht[i]==0&&i==del){
continue;
}
}
}
for(int i=node[start].rear;i!=-1;){
printf("%d ",i);
i=node[i].rear;
}
return 0;
}
2 队列
2.1 使用STL实现队列
洛谷P1540 [NOIP2010 提高组] 机器翻译
#include<bits/stdc++.h>
using namespace std;
queue<int>words;
int hasht[1005]={0};
int mem=0;
int count1=0;
int main(){
int m,n;
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++){
int temp;
scanf("%d",&temp);
if(hasht[temp]==0){
hasht[temp]=1;
count1++;
mem++;
if(mem<=m)
words.push(temp);
else if(mem>m){
hasht[words.front()]=0;
words.pop();
words.push(temp);
mem--;
}
}
}
cout<<count1;
return 0;
}
2.2 用STL实现单调队列
P1886 滑动窗口 /【模板】单调队列
60分除了超时都对代码:
#include<bits/stdc++.h>
using namespace std;
int num[100005]={0};
int q[100005];
int p[100005];
int head=0,tail=0;
int n,k;
void minop(){
head=1;
tail=0;
for(int i=1;i<=n;++i){
while(head<=tail&&q[tail]>num[i]){
tail--;
}
q[++tail]=num[i];
p[tail]=i;
while(p[head]<=i-k){
head++;
}
if(i>=k)printf("%d ",q[head]);
}
}
void maxop(){
head=1;
tail=0;
for(int i=1;i<=n;i++){
while(head<=tail&&q[tail]<=num[i]){
tail--;
}
q[++tail]=num[i];
p[tail]=i;
while(p[head]<=i-k){
head++;
}
if(i>=k)printf("%d ",q[head]);
}
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
minop();
printf("\n");
maxop();
return 0;
}
3 栈
3.1 使用STL实现栈
hdu 1062 Text Reverse
这道题和字符串操作有关,比较重要。
通过代码:
#include<bits/stdc++.h>
using namespace std;
int t;
int main(){
scanf("%d",&t);
char ch=getchar();
int flag=0;
while(t--){
stack<char> s;
string str;
getline(cin,str);
int i=0;
while(flag!=1){
if(str[i]=='\0')
flag=1;
if(str[i]==' '||str[i]=='\0'){
while(s.empty()==0){
printf("%c",s.top());
s.pop();
}
printf(" ");
i++;
continue;
}
s.push(str[i]);
i++;
}
flag=0;
printf("\n");
}
return 0;
}
3.2 单调栈
P2947 [USACO09MAR] Look Up S
题解代码:
#include<bits/stdc++.h>
using namespace std;
stack<int>height;
int num[100005];
int out[100005];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
out[n]=0;
height.push(n);
for(int i=n-1;i>=1;i--){
if(num[i]<num[height.top()]){
out[i]=height.top();
height.push(i);
}else if(num[i]>=num[height.top()]){
while(height.empty()!=1&&num[i]>=num[height.top()]){
height.pop();
}
if(height.empty()==1){
out[i]=0;
}else{
out[i]=height.top();
}
height.push(i);
}
}
for(int i=1;i<=n;i++){
printf("%d\n",out[i]);
}
return 0;
}
4 树
4.1建立二叉树和遍历二叉树
hdu1710 Binary Tree Traversals
输出超出但是理解没问题代码:
#include <iostream>
int preorder[1005];
int inorder[1005];
struct Node {
int data;
Node* lchild, * rchild;
Node() {
lchild = NULL;
rchild = NULL;
}
}node[1005];
Node* t = &node[0];
int cnt = 1;
void buildtree(Node* tr, int prest, int prend, int inst, int innd) {
if (prest > prend)return;
tr->data = preorder[prest];
if (prest == prend)return;
int index = -1;
for (int i = inst; i <= innd; i++) {
if (preorder[prest] == inorder[i]) {
index = i;
break;
}
}
if (index == -1)return;
int distance = index - inst;
if (index == inst) {
tr->rchild = &node[cnt++];
buildtree(tr->rchild, prest + 1, prend, inst + 1, innd);
}
else if (index == innd) {
tr->lchild = &node[cnt++];
buildtree(tr->lchild, prest + 1, prend, inst, innd - 1);
}
else {
tr->lchild = &node[cnt++];
tr->rchild = &node[cnt++];
buildtree(tr->lchild, prest + 1, prest + distance, inst, index - 1);
buildtree(tr->rchild, prest + distance + 1, prend, index + 1, innd);
}
}
void printpost(Node* tre) {
if (tre == NULL) {
return;
}
printpost(tre->lchild);
printpost(tre->rchild);
printf("%d ", tre->data);
}
int main() {
int n;
//初始化
while (~scanf("%d", &n)) {
cnt = 1;
for (int i = 0; i < n; i++) {
scanf("%d", &preorder[i]);
}
for (int i = 0; i < n; i++) {
scanf("%d", &inorder[i]);
}
buildtree(t, 0, n - 1, 0, n - 1);
printpost(t);
printf("\n");
}
return 0;
}
P1087 [NOIP2004 普及组] FBI 树
ac代码
#include<iostream>
#include<string>
using namespace std;
string num1;
int n;
struct Node {
char c;
Node* lchild, * rchild;
Node() :lchild(0), rchild(0) {}
};
Node* t = new Node();
char typeof1(string strr) {
char a = strr[0];
for (int i = 0; i < strr.size(); i++) {
if (strr[i] != a) {
return 'F';
}
}
if (a == '0')return 'B';
else if (a == '1')return 'I';
}
void buildtree(Node* tt, string str) {
if (str.size() == 1) {
tt->c = typeof1(str);
return;
}
tt->c = typeof1(str);
tt->lchild = new Node();
tt->rchild = new Node();
buildtree(tt->lchild, str.substr(0, str.size() / 2));
buildtree(tt->rchild, str.substr(str.size() / 2));
}
void printtree(Node* tre) {
if(tre->lchild) printtree(tre->lchild);
if (tre->rchild)printtree(tre->rchild);
printf("%c", tre->c);
}
int main() {
cin >> n;
cin >> num1;
buildtree(t, num1);
printtree(t);
return 0;
}
第30次ccf认证
1.重复局面
代码:
#include <bits/stdc++.h>
using namespace std;
int n;
char pieces[64];
map <string,int> states;
int main() {
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<64;j++)
cin>>pieces[j];
if(states.count(pieces))
states[pieces]++;
cout<<states[pieces]<<endl;
}
return 0;
}
2.