Bootstrap

普及刷题总结

P1012 选数

bool cmp(string x,string y){
	return x + y > y + x;//字符串的比较 
}

P1029 最大公约数和最小公倍数问题 -------[数学]

P1029

//Author:PhilFan;
#include<bits/stdc++.h>
using namespace std;
long long cnt,x,y; 
long long gcdd(long long a, long long b){
	if(b == 0)	return a;
	else return gcdd(b,a%b);
}
int main()
{
	cin>>x>>y;
	for(long long i = 1; i <= y/x;i++){
		for(long long j = 1;  j <= y/x;j ++){
			if(x * i * j == y && gcdd(x*i,x*j) == x){
				cnt++;
			}
		}
	}
	cout<<cnt<<endl;
	return 0;
}

P1255 数楼梯 ------------[高精]

数楼梯
Fibonacci + 高精

2019.11.22
daerwen大佬今天红了
今天学了一下高精,其实就是相当于手动列竖式,然后处理进位;就很麻烦与简单

#include<bits/stdc++.h>
using namespace std;
int a[1300],b[1300],c[1300]; 
int n;
void pplus(int *a,int *b){//高精加 
	int jw = 0;
	for(int i = 1;i <= 1200; i++){
		c[i] = a[i] + b[i] + jw;
		jw = c[i]/10;
		c[i]%=10;
	}
}
int main(){
	cin>>n;
	if(n<= 3){
		cout<<n<<endl;
		return 0;
	}
	a[1] = 1;b[1] = 2;
	for(int i = 3; i <= n;i++){
		pplus(a,b);
		memcpy(a,b,sizeof b);
		memcpy(b,c,sizeof c); //复制去处, 被复制 ,被复制长度 
	}
	
	//输出 
	bool fl = 0;
	for(int i = 1200; i >= 1;i--){
		if(b[i] != 0)	fl = 1;
		if(fl)cout<<b[i];
	}
	return 0;
}

P1009 阶乘之和----------------[高精]

2019.11.22
阶乘之和
又是一道高精题

multiplication 乘法 简称 mul
addition 加法 简称 add

#include<bits/stdc++.h>
using namespace std;
int a[1000],b[1000],c[1000];
int sum[1000];
int n;
void pplus(int *a,int *c){//加法
	int jw = 0;
	for(int i = 1; i <= 1000;i++){
		c[i] += a[i] + jw;
		jw = c[i]/10;
		c[i] %= 10;
	}
}
void mul(int *a,int m){//乘法
	int jw = 0;
	for(int i = 1;i <= 1000; i++){
		a[i] = a[i] * m + jw;
		jw = a[i]/10;
		a[i] %= 10; 
	}
} 
int main(){
	cin>>n;
	a[1] = 1;
	for(int i = 1;i <= n;i++){
		mul(a,i);
		pplus(a,c);
	}
	bool fl = 0;
	for(int i = 1000; i >= 1; i--){
		if(c[i] != 0)	fl = 1;
		if(fl)	cout<<c[i];
	}
	return 0;
}

P1981 表达式求值

表达式求值

python3 最为致命

print(input()%10000)
//Author:PhilFan;
#include<bits/stdc++.h>
using namespace std;
int main()
{
	long long shu,ji,ans = 0,sg;
	char ch = 0, xg;
	bool tf = true;
	while(tf){
		scanf("%lld",&shu);
		tf = (scanf("%c",&xg) == 1 )? true:false;
		if(ch == 0)		ji = shu;
		if(ch == '+') 	ans = (ans + ji) %10000,ji = shu; 
		if(ch == '*') 	ji = (ji * shu) %10000;
		if(!tf) ans = (ans + ji )%10000;
		ch = xg;
	} 
	printf("%lld",ans);
	return 0;
}

P1030 求先序排列------------[树学]

求先序排列

//Author:PhilFan;
#include<bits/stdc++.h>
using namespace std;
string frt,bck;
int len; 
int find(char ch){
	for(int i = 0;  i < len;i++){
		if(ch == frt[i]){
			return i;
		}
	}
}
void dfs(int la,int ra,int lb,int rb){//中序起点 中序终点 后序起点 后序终点 
//	if(la>ra)return;
	cout<<bck[rb];
	int m = find(bck[rb]);
	//我们现在知道中序和后序
	// 也就是 后续最后一个点就是当前子树的根节点,
	// 我们找到了后续排列中的最后一个点在中序排列中的位置,就要知道我们左边的子树到底有多少,右边的子树有多少
	// m 是 后序根节点在中序中的位置 
	if(m > la)//左边的子树
		dfs(la,m-1,lb,rb-(ra-m)-1);
	if(m < ra) //右边的子树 
		dfs(m+1,ra,lb+m-la,rb-1);
} 
int main()
{
	cin>>frt;
	cin>>bck;
	len = frt.length();
	dfs(0,len-1,0,len-1);
	return 0;
}

P5663 加工零件

P5663 加工零件

2019 CSP-J T4
这道题告诉我,对于一些题目,我们需要找出一些题目中隐藏的性质;

这道题 ,我们注意到,

  • 与1号点位距离为偶数,并且生产需求是偶数的,1就必须提供原材料
  • 而反之,与1号点距离为奇数,并且生产需求是奇数的,1也必须提供原材料
  • 生产需求小于1到此点的最短路,就生产不了

基于这三点基本概念,我们可以想到 最短路BFS + 奇偶数判断 的做法,这样就可以get 95 pts
在这里插入图片描述
还有一种比较坑爹的情况,就是1号点位与其他工人都不相连,所以一号点的需求就没人接受,别人的需求1号点也做不到,所以都输出no
实现方法挺简单的,就是判断一下1号点有没有边与它相连就好了

#include<bits/stdc++.h>
using namespace std;
#define maxn 105000
int n,m,q,cnt;
int hd[maxn*2];
struct Node{
	int sig;//奇数最短路 
	int dbl;//偶数最短路 
}dis[maxn*2];// dis[maxn<<1] 其实不需要乘2 但是为了保险 

struct Edge{
	int to,nxt,w;
}edge[maxn*2];// edge[maxn<<1]; 
void add(int u ,int v){
	cnt++;	
	edge[cnt].to = v;
	edge[cnt].nxt = hd[u];
	hd[u] = cnt;
}

void bfs(){//宽搜 然后需要维护一个奇偶数最短路数组 
	queue <int> q;
	dis[1].dbl = 0;//1到1 可以走偶数次0 到达; 而1 到 1不可以走奇数次到达 
	q.push(1);
	while(!q.empty()){
		int u = q.front();q.pop();
		for(int j = hd[u]; j != -1; j = edge[j].nxt){
			int v = edge[j].to;int x = dis[v].dbl ; int y = dis[v].sig;
			dis[v].dbl = min(dis[v].dbl,dis[u].sig + 1);//用奇数更新偶数 //min写法
			dis[v].sig = min(dis[v].sig,dis[u].dbl + 1);//用偶数更新奇数 
//			if(dis[v].dbl > dis[u].sig + 1){
//				dis[v].dbl = dis[u].sig + 1; 
//				fl = 1;
//			}
//			if(dis[v].sig > dis[u].dbl + 1){
//				dis[v].sig = dis[u].dbl + 1; 
//				fl = 1;									//松弛写法 
//			}
			if(dis[v].dbl != x|| dis[v].sig != y) q.push(v);//如果被更新过,就入队 
		}
	}
}
int main(){
//	freopen("work.in","r",stdin);
//	freopen("work.out","w",stdout);//freopen 不要写错!! 不要注释掉~~!!!! 
	cin>>n>>m>>q;
	memset(hd,-1,sizeof hd);
	for(int i = 1; i <= n+5;i++){//初始化最短路,全部都到达不了 
		dis[i].dbl = 0x3f3f3f3f;
		dis[i].sig = 0x3f3f3f3f;
	}	
	for(int i = 1; i<= m;i++){
		int u,v;
		cin>>u>>v; 
		add(u,v);
		add(v,u);//双向边 
	}
	bfs();
//	for(int i = 2;i <= n;i++){
//		printf("第%d个 sig = %d dbl =%d\n",i,dis[i].sig,dis[i].dbl);
//	}
//	printf("%d",hd[1]); 
	for(int i = 1; i <= q; i ++){
		int id,l;
		cin>>id>>l;
		if(hd[1] == -1){
			printf("No\n");continue;	//注意到: 点1 可能和其他点没有边 这时候无论什么情况都输出no 
		}
		if((l%2==1) && (dis[id].sig <= l) ){	//奇数需求 并且 奇数最短路 
			printf("Yes\n");continue;
		}
		else if((l%2==0) && (dis[id].dbl <= l) ){//偶数需求 并且偶数最短路 
			printf("Yes\n");continue;
		}
		else cout<<"No"<<endl;// 非正常情况 都是no 
	}
	return 0;
}
;