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掉这道题,只用注意细节就行了。