2020.11.19考试学习笔记

早上:

T1:sum

关于这种比较水的数据,可以选择打个表,然后观察规律。或者直接打答案的表
可以发现,从第三位开始,6位一循环,所以用数学做法简单的操作一下就可以了。
例如:0.10112310112310……
另num2=99999900,num1={循环数},x=第一二位数,y=100
输出\((num1\times y+num2\times x) / (num2\times y)\)
记得约分

T2:form

物理题,暴力算,个人不是很喜欢这种题,所以不想多谈

T3:dam

模拟栈的操作就可以了,推荐手写栈,因为函数栈比较慢。

#include<bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a),i##i=(b);i<=i##i;i++) 
#define ROF(i,a,b) for(int i=(a),i##i=(b);i>=i##i;i--)
#define REP(eg,u) for(int eg=h[(u);eg;eg=nxt[eg]])
#define ll long long
#define db double
#define I inline int
#define V inline void
#define B inline bool
#define F(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
#define int ll 
// = = = = = = = = = line = = = = = = = = = //
const int N = 1e5;
bool cmp(pair<int,int>a,pair<int,int>b) {
	return a.first > b.first;
}
// = = = = = = = = = nums = = = = = = = = = //
template<typename T>
class Mystack{
	T date[N];
	int tl,hd;
public:
	Mystack(){tl = -1,hd = 0;}
	B empty(){return hd > tl;}
	I size(){return tl-hd+1;}
	V push(T x) {date[++tl]=x;}
	V pop() {tl--;}
	T top(){return date[tl];}
};
string ORDER="";
Mystack<vector<pair<int,int> > > Q;
// = = = = = = = = = input = = = = = = = = = //
V input() {
	cin >> ORDER;
	vector<pair<int,int> >a;
	pair<int,int>tem = make_pair(1,1);
	a.push_back(tem);
	Q.push(a);
}
// = = = = = = = = = work = = = = = = = = = //
V work() {
	int l = ORDER.size();
	vector<pair<int,int> >a1,a2;
	FOR(k,0,l-1){
		if(ORDER[k] == 'D') {
			a1 = Q.top();
			Q.push(a1);
		} else if(ORDER[k] == 'A') {
			a1 = Q.top(),Q.pop();
			a2 = Q.top(),Q.pop();
			int l1 = a1.size();
			for(int i = 0; i < l1; i++){
				a2.push_back(a1[i]);
			}
			sort(a2.begin(),a2.end(),cmp);
			int l2 = a2.size();
			for(int i = 0; i <= l2-2; i++) {
				while(a2[i].first == a2[i+1].first && i + 1 < l2) {
					a2[i].second += a2[i+1].second;
					l2--;
					a2.erase(a2.begin()+i+1);
				}
			}
			Q.push(a2);
		} else {
			a1 = Q.top(),Q.pop();
			a2 = Q.top(),Q.pop();
			vector<pair<int,int> > tem;
			tem.clear();
			int l1 = a1.size(),l2=a2.size();
			FOR(i,0,l1-1) FOR(j,0,l2-1) {
				tem.push_back(make_pair(a1[i].first + a2[j].first,a1[i].second * a2[j].second));
			}
			int l3 = tem.size();
			sort(tem.begin(),tem.end(),cmp);
			for(int i = 0; i <= l3 - 2; i++) {
				while(tem[i].first == tem[i+1].first) {
					tem[i].second += tem[i+1].second;
					l3--;
					tem.erase(tem.begin()+i+1);
				}
			}
			Q.push(tem);
		}
	}
	return;
}
// = = = = = = = = = print = = = = = = = = = //
V print(){
	vector<pair<int,int> >ans;
	ans = Q.top();
	bool flag = true;
	int l = ans.size();
	FOR(i,0,l-1) {
		if(ans[i].second == 0) {
			continue;
		} else if(flag) {
			if(ans[i].second == 1 && ans[i].first == 1) printf("x");
			else if(ans[i].first == 1) printf("%lldx",ans[i].second);
			else if(ans[i].second == 1) printf("x^%lld",ans[i].first);
			else printf("%lldx^%lld",ans[i].second,ans[i].first);
			flag = false;
		} else {
			if(ans[i].second == 1 && ans[i].first == 1) printf("+x");
			else if(ans[i].first == 1) printf("+%lldx",ans[i].second);
			else if(ans[i].second == 1) printf("+x^%lld",ans[i].first);
			else printf("+%lldx^%lld",ans[i].second,ans[i].first);
		}
	}
	return;
}
// = = = = = = = = = main = = = = = = = = = //
signed main() {
	F("dam");
	input();
	work();
	print();
	return 0;
}
/*
DADDMA
*/

T4:game

动态规划+组合数学题,组合数学还没有学得太深,所以考场上直接输案例得了20分。美滋滋

晚上:

四道水题!!!!!!
艹(一种植物)!

T1:sub

裸的高精减。

#include<bits/stdc++.h>
using namespace std;
#define F(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
string a,b,ans;
bool operator<(string a,string b) {
	int l1 = a.size(),l2 = b.size();
	if(l1 < l2) return true;
	else if(l1 > l2) return false;
	else {
		for(int i = 0; i < l1; i++) {
			if(a[i] > b[i]) return false;
			else if(a[i] < b[i]) return true;
		}
	}
	return false;
}
int main() {
	F("sub");
	bool flag1 = 1,flag2 = 1,flag = 1;
	cin >> a >> b;
	if(a == b) {
		cout << 0;
		return 0;
	}
	if(a[0] == '-') flag1 = 0,flag ^= 1,a.erase(a.begin(),a.begin()+1);
	if(b[0] == '-') flag2 = 0,flag ^= 1,b.erase(b.begin(),b.begin()+1);
	if(!flag1 && !flag2)swap(a,b);
	if(!flag1 && flag2) {putchar('-');if(a < b) swap(a,b);}
	if(a < b && (flag1 + flag2 != 1)) putchar('-'),swap(a,b);
	if(flag1 && !flag2) if(a < b) swap(a,b);
	int l1 = a.size(),l2 = b.size();
	for(int i = 1; i <= l1 - l2; i++)b = "0" + b;
	if(flag) 
		for(int i = l1 - 1,j = 0; i >= 0; i--) {
			int s = a[i] - b[i] - j;
			if(s < 0) j = 1,s += 10;else j = 0;
			char ch = s + 48;
			ans = ch + ans;
		} 
	else {
		int j = 0;
		for(int i = l1 - 1; i >= 0; i--) {
			int s = (a[i] ^ 48) + (b[i] ^ 48) + j;
			j = s / 10,s %= 10;
			char ch = s + 48;
			ans = ch + ans;
		}
		if(j) ans = '1' + ans;
	}
	while(ans[0] == '0')ans.erase(ans.begin(),ans.begin()+1);
	if(ans.size() == 0) ans = "0";
	cout << ans;
	return 0;
} 

T2:sort

比较简单的逆序对算法,由于\(n\le10000\),所以\(O(n^2)\)直接暴力也不是不行。

#include<bits/stdc++.h>
using namespace std;
#define F(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
int a[10010];
int main() {
	F("sort");
	long long ans = 0;
	int n;
	cin >> n;
	for(int i = 1; i <= n ;i++) {
		cin >> a[i];
	}
	for(int i = 1; i < n; i++) {
		for(int j = i + 1; j <= n; j++) {
			if(a[i] > a[j]) ans++;
		}
	}
	cout << ans;
	return 0;
}
/*
5 3 1 4 5 2 
*/

但是,为了更优秀的算法,我们可以考虑归并排序。

#include<bits/stdc++.h>
using namespace std;
#define F(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
int n,a[10010];
int t[10010];
long long ans = 0;
inline void g_sort(int lef,int rig) {
	if(lef == rig) return;
	int mid = (lef + rig) >> 1;
	g_sort(lef,mid);
	g_sort(mid+1,rig);
	int i = lef,j = mid+1;
	int k = lef;
	while(i <= mid && j <= rig) {
		if(a[i] <= a[j]) t[k] = a[i],i++,k++;
		else t[k] = a[j],j++,k++,ans += (mid - i + 1);
	}
	while(i <= mid)t[k] = a[i],k++,i++;
	while(j <= rig)t[k] = a[j],k++,j++;
	i = lef;
	while(i <= rig)a[i] = t[i],i++;
}
int main() {
	F("sort");
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> a[i];
	g_sort(1,n);
	cout << ans;
	return 0;
}

T3:dna

跟上题一样,\(n\le10000\),直接\(O(n^2)\)暴力就能出答案,标准的写法可以用kmp来\(O(n)\),或者用更为优秀的AC自动机和后缀自动机,不多做介绍。

#include<bits/stdc++.h>
#define gc getchar()
using namespace std;
#define F(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
string s;
string a;
int ans = 0;
int main() {
	F("dna");
	char ch = gc;
	while(ch != '.') {
		if(ch >= 'A' && ch <= 'Z') s = s + ch;
		ch = gc;
	}
	ch = gc;
	while(ch < 'A' || ch > 'Z') ch = gc;
	while(ch >= 'A' && ch <= 'Z') {
		a = a + ch;
		ch = gc;
	}
	int l1 = s.size(),l2=a.size();
	for(int i = 0; i <= l1 - l2; i++) {
		bool flag = true;
		for(int j = 0; j < l2 ;j++) {
			if(a[j] != s[i+j]) {
				flag = false;
				break;
			}
		}
		if(flag) ans++;
	}
	cout << ans;
	return 0;
}
/*
ATGGGACTAGACATAGCACAATTAATTAAACAGAGCATAGAGAGACACTAATAAATTAATTAAAGAATCAGATCAGACATACAGGGAGAGAGAGAGGGGGACACATAGACACAAAACAGAGAATTAATTAATTAAAGAGGACAGAGAGCA.
AATTAATTAA
*/

时隔几个月来补一下 KMP 算法。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define F(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
const int N = 1e4 + 1;
char s[N],t[N];
int nxt[N];
int main() {
    F("dna");
    scanf("%s%s",s + 1,t + 1);
    int l1 = strlen(s + 1),l2 = strlen(t + 1);
    l1--;//去个点
    for(int i = 2,j = 0; i <= l2; i++) {
        while(j && t[j + 1] != t[i]) j = nxt[j];
        if(t[j + 1] == t[i]) j++;
        nxt[i] = j;
    }
    int ans = 0;
    for(int i = 1,j = 0; i <= l1; i++) {
        while(j && t[j + 1] != s[i]) j = nxt[j];
        if(t[j + 1] == s[i]) j++;
        if(j == l2) ans++;
    }
    cout << ans << endl;
    return 0;
}

T4:back

if语句的熟练运用就可以A掉这道题,只用注意细节就行了。

posted @ 2020-11-19 21:36  Kamiya-Kina  阅读(128)  评论(0编辑  收藏  举报