PAT A1093 Count PAT & A1097 Deduplication on a Linked List

题目描述

在这里插入图片描述

知识点

思维

实现

码前思考

  1. 看到数据集的大小是 1 0 5 10^5 105,那么基本可以确认,不能使用 O ( N 2 ) O(N^2) O(N2)的算法,那么又要遍历每一个字母,所以必然是大于等于 O ( N ) O(N) O(N)的算法;
  2. 如果采用 O ( N ) O(N) O(N)的算法,意味着不能在i时,查看0...i-1的每个数,那么就要使用空间换时间的思想;
  3. 根据题目的含义,动手模拟一下,就知道可以使用 计数 的思想实现;

代码实现

#include <cstdio>
#include <iostream>
#include <string>
#include <map>
using namespace std;
const int mod = 1000000007;
map<string,long long> mp;
string input;

int main(){
	cin>>input;
	int len = input.size();
	for(int i=0;i<len;i++){
		char c = input[i];
		if(c == 'P'){
			mp["P"] = (mp["P"]+1)%mod;
		}else if(c == 'A'){
			mp["PA"] = (mp["PA"]+mp["P"])%mod;
		}else if(c == 'T'){
			mp["PAT"] = (mp["PAT"]+mp["PA"])%mod;
		}
	}
	
	printf("%lld\n",mp["PAT"]);
}
 

码后反思

  1. 对于取模1000000007,最好是每一步都取模,并且使用long long类型防止在运算时溢出!
  2. long long输入和输出要使用lld

题目描述

在这里插入图片描述

知识点

静态链表

实现

码前思考

  1. 通过两个虚拟结点,一个结点指向原始去重后链表,一个结点指向被去重元素链表;
  2. 然后就是注意细节操作就好了,其实不难;

代码实现

#include <cstdio>
#include <algorithm> 
using namespace std;
const int maxn = 1e5+10;
bool v[maxn];

int N;
int start;

struct node{
	int key;
	int next;
};

node list[maxn];

int main(){
	fill(v,v+maxn,false);
	scanf("%d %d",&start,&N);
	while(N--){
		int idx;
		scanf("%d",&idx);
		scanf("%d %d",&list[idx].key,&list[idx].next);
	}
	
	//从第一个key开始寻找
	int preBefore = 100004;
	list[preBefore].next = -1;
	int preRemove = 100005;
	list[preRemove ].next = -1;
	int cur = start;
	
	while(cur != -1){
		int key = abs(list[cur].key);
		if(v[key] == false){
			v[key] = true;
			list[preBefore].next = cur;
			preBefore = cur;
			cur = list[cur].next;
			//设置为-1 
			list[preBefore].next = -1; 
		}else{
			list[preRemove].next = cur;
			preRemove = cur;
			cur = list[cur].next;
			//设置为-1 
			list[preRemove].next = -1; 
		}

	}
	
	int before = list[100004].next;
	int remove = list[100005].next;
	while(before != -1){
		printf("%05d %d",before,list[before].key);
		if(list[before].next!=-1){
			printf(" %05d\n",list[before].next);
		}else{
			printf(" -1\n");
		}
		before = list[before].next;
	}
	while(remove != -1){
		printf("%05d %d",remove,list[remove].key);
		if(list[remove].next!=-1){
			printf(" %05d\n",list[remove].next);
		}else{
			printf(" -1\n");
		}
		remove = list[remove].next;		
	}
	 
	return 0;
}

码后反思

  1. 在变量命名的时候还是要仔细,尽量命名一些容易理解的名字,虽然有时候会很长,但是太短了难理解也不行啊!
  2. 像下面这种涉及到一个变量的相继的取值和赋值的代码要特别小心,到底是先赋值还是先取值,要理清顺序~
    preBefore = cur;
    cur = list[cur].next;
    //设置为-1 
    list[preBefore].next = -1; 
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值