第一次打12个小时的比赛…记录一下比赛的经历.
早上八点就起来肝了.毕竟知道做不了很多题.只能靠罚时苟一苟名次…
比赛比起平时无压力做题的时候确实要更加激发人的思维.这次比赛基本上自己能力范围内的题都做了.写了13个水题+1个不太水的题(S).L题带权lis感觉要用个线段树一类的结构优化.由于在这方面造诣不精.只能靠O2和set苟了前面七个数据点.(L题题解已经更新)
R题dp一直想不到好的思路dp.等官方题解出来再看吧…值得一提的是S的trie.刚学trie树就来了一道trie树的好题.待会题解会说具体思路.剩下的4题显然不在我的能力范围内…就不多提了.
因为大部分题算是暴力题.代码不会很优雅.码风以暴力为主.
A模拟就不多说了.判非法就好了.要注意的是除了日期有非法.信息也有非法.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int y,m,d;
int u[13] = {1,31,28,31,30,31,30,31,31,30,31,30,31};
bool run(int year){
return year % 4 == 0 && year % 100 || year % 400 == 0;
}
bool judge(string s){
if(s.size() != 8) return false;
fir(i,0,s.size()-1) if(!isdigit(s[i])) return false;
y=0,m=0,d=0;
fir(i,0,3) y = y*10+s[i]-'0';
if(y > 2020 || y < 1900) return false;
fir(i,4,5) m = m*10+s[i]-'0';
if(m < 1 || m > 12) return false;
fir(i,6,7) d = d*10+s[i]-'0';
if(run(y) && m == 2){
if(d < 1 || d > 29) return false;
return true;
}
if(d < 1 || d > u[m]) return false;
return true;
}
int main(){
string s1,s2;
while(getline(cin,s1)){
getline(cin,s2);
if(!judge(s1)){
puts("none");
continue;
}
bool f1= 0;
fir(i,0,s2.size()-1){
if(!isalpha(s2[i]) && s2[i] !=' '){
puts("none");
f1=1;
break;
}
}
if(f1) continue;
int cur = 0;
fir(i,0,s1.size()-1){
cur += s1[i]-'0';
}
int tmp = 0;
while(cur >= 10){
tmp = cur;
int ctmp=0;
while(tmp){
ctmp+=tmp%10;
tmp/=10;
}
cur = ctmp;
}
fir(i,0,s2.size()-1){
if(s2[i] == ' ') s2[i] = '#';
else {
if(s2[i] >= 'a' && s2[i] <= 'z'){
char ss = (s2[i]-'a'+cur)%26+'a';
s2[i] =ss;
}
else{
char ss = (s2[i]-'A'+cur)%26+'A';
s2[i] =ss;
}
}
}
cout << s2 << endl;
}
return 0;
}
B题关键点其实就是怎么算天数.有个模板是能算0年开始-xxxx年的天数.和前缀和一样减一下就知道天数了.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
const int mod = 9901;
LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a % b); }
int us[4] = {4,1,2,3};
int f(int y, int m, int d) {
if (m < 3){
y--;
m += 12;
}
return 365 * y + (y >> 2) - y / 100 + y / 400 + (153 * m - 457) / 5 + d - 306;
}
int main() {
int y,m,d;
int st=f(2000,1,1)-1;
while(cin >> y >> m >> d){
int cur = f(y,m,d)-st;
int ans1 = cur%4?cur/4+1:cur/4;
cout << ans1 << ' ' << us[cur%4] << endl;
}
return 0;
}
C题就是map的运用题吧…怎么暴力怎么来.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
#include <sstream>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
map<string,int> mp;
int main(){
string s;
int cnt;
while(getline(cin,s)){
if(s[0] == '#') break;
stringstream s1(s);
string tmp;
cnt=0;
while(s1 >> tmp){
cnt++;
mp[tmp]++;
}
int n=0;
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();++it){
if(it->second == 1) n++;
}
if(cnt <= 2*n) puts("yes");
else puts("no");
mp.clear();
}
return 0;
}
D题用一个vector存三个组就ok了.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int a[N];
int b[N];
vector<int> ans[3];
int main(){
int n;
cin >> n;
int cnt=0;
fir(i,1,n){
cin >> a[i];
ans[cnt].pb(a[i]);
cnt++;
if(cnt > 2) cnt=0;
}
fir(i,0,2){
if(ans[i].size()){
cout << ans[i][0];
fir(j,1,ans[i].size()-1) cout << " " << ans[i][j];
}
cout << endl;
}
return 0;
}
G题,桶排暴力遍历一遍.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int num[N];
int a[N];
int main(){
int n;
cin >> n;
fir(i,1,n){
cin >> a[i];
num[a[i]]++;
}
int maxx=0,ans=0;
fir(i,1,n){
if(num[a[i]] > maxx){
ans = a[i];
maxx = num[a[i]];
}
}
cout << ans << endl;
return 0;
}
I题重载一下小于号直接排序就完事了
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
struct Node{
int a,b,c,p;
bool operator<(const Node&x) const{
if(a + b + c == x.a+x.b+x.c){
if(c == x.c) return p < x.p;
return c > x.c;
}
return a+b+c > x.a+x.b+x.c;
}
}node[N];
int main(){
int n;
cin >> n;
fir(i,1,n){
cin >> node[i].c >> node[i].a >> node[i].b;
node[i].p = i;
}
sort(node+1,node+1+n);
fir(i,1,n){
if(i >= 6) break;
cout << node[i].p << " " << node[i].c << " " << node[i].a << " " << node[i].b << endl;
}
return 0;
}
J题嘛…暴力美学做法:纸上模拟一下旋转可以发现只要一开始按顺序存好数.旋转完之后就是起点变了然后循环8个数就ok了…突出一个暴力.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int us[10];
vector<int> u;
int c;
int f(int p){
int res = 0;
int k = 1;
fir(i,0,7){
res += (u[(p+i)%8] ^ c)*us[k++];
}
return res;
}
int main(){
int n;
cin >> n;
int tmp = pow(2,7);
fir(i,1,8){
us[i] = tmp;
tmp>>=1;
}
while(n--){
string s;
cin >> s;
u.clear();
fir(i,0,8){
if(i == 4){
c = s[i] == '0'?0:1;
continue;
}
}
fir(i,0,2) u.pb(s[i] == '0'?0:1);
u.pb(s[5]=='0'?0:1);
afir(i,8,6) u.pb(s[i] == '0'?0:1);
u.pb(s[3] == '0'?0:1);
int ans = min(f(0),min(min(f(6),f(4)),f(2)) );
cout << ans << endl;
}
return 0;
}
K题,贪心题.正确性不会证…按完成时间排序就好了.但比赛的时候可以靠过题人数来猜测这题肯定不难所以做法正确^^
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
pii tk[N];
bool cmp(pii a,pii b){
return a.sd > b.sd;
}
int main(){
int n;
cin >> n;
cout << "Project " << n << ": ";
int ans = 0;
fir(i,1,n){
cin >> tk[i].ft >> tk[i].sd;
}
sort(tk+1,tk+1+n,cmp);
int ti=0,last = 0;
fir(i,1,n)
{
last = max(last,ti+tk[i].ft+tk[i].sd);
ti += tk[i].ft;
}
cout << last;
return 0;
}
L题虽然没做出来但是也说一下思路吧.可以知道的是价值是负数和0的鱼是肯定不会选的,所以可以先预处理排除掉它们.然后就是带权的lis了.由于要找区间最值…学艺不精,线段树和树状数组都不太熟练.靠set+奇奇怪怪的优化硬跑了7个点后TLE了. 题解已经更新
瞎搞的代码
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
struct Fish{
int v,s;
bool operator<(const Fish& x) const{
if(x.s == s) return v > x.v;
return s < x.s;
}
};
int a[N],v[N];
int main(){
int t,tot=0;
scanf("%d",&t);
while(t--){
int n;
printf("Case #%d: ",++tot);
scanf("%d",&n);
int ans = -1e9;
vi va,sa;
va.pb(0);
sa.pb(-1e9);
fir(i,1,n){
scanf("%d",a+i);
v[i] = a[i]/10000;
a[i] %= 10000;
ans = max(v[i],ans);
if(v[i] <= 0) continue;
va.pb(v[i]);
sa.pb(a[i]);
}
if(ans <= 0){
cout << ans << endl;
continue;
}
ans = 0;
n = va.size()-1;
set<Fish> st;
Fish sta = {va[1],sa[1]};
st.insert(sta);
fir(i,2,n){
Fish cur = {va[i],sa[i]};
vector<Fish> vec;
set<Fish>::iterator itw = st.upper_bound(cur);
for(set<Fish>::iterator it = st.begin();it!=itw;++it){
cur.v = max(cur.v,va[i]+(*it).v);
ans = max(cur.v,ans);
}
for(set<Fish>::iterator it = itw; it !=st.end();++it){
if(cur.v >= (*it).v){
vec.pb(*it);
}
}
if(vec.size()){
fir(i,0,vec.size()){
st.erase(vec[i]);
}
}
st.insert(cur);
}
st.clear();
sta = {va[n],sa[n]};
st.insert(sta);
afir(i,n-1,1){
Fish cur = {va[i],sa[i]};
set<Fish>::iterator itw = st.upper_bound(cur);
vector<Fish> vec;
for(set<Fish>::iterator it = st.begin();it!=itw;++it){
cur.v = max(cur.v,va[i]+(*it).v);
ans = max(cur.v,ans);
}
for(set<Fish>::iterator it = itw; it !=st.end();++it){
if(cur.v >= (*it).v){
vec.pb(*it);
}
}
if(vec.size()){
fir(i,0,vec.size()){
st.erase(vec[i]);
}
}
st.insert(cur);
}
printf("%d\n",ans);
}
return 0;
}
/*
v 在-6 - 6的范围里.
*/
m题.set暴力模拟就完事了.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int f[N];
int cnt=0;
set<int> ys;
int main(){
int x,y;
int ans= 0;
while(cin >> x){
if(x == -1) break;
cin >> y;
int up = 0;
if(!ys.count(x)) up++;
if(!ys.count(y)) up++;
if(ys.size()+up == cnt+1){
ans++;
continue;
}
cnt++;
ys.insert(x);
ys.insert(y);
}
cout << ans;
return 0;
}
N题读懂题面就没什么难度了…算出下标映射后的值后用pair或者结构体排序一下就完事了
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int n;
pii mp[N*N];
int get(int r,int c){
int res = 0;
int bit=0;
while(r || c){
if(bit&1){
res += (r&1) << bit;
r>>=1;
}
else{
res += (c&1) << bit;
c>>=1;
}
bit++;
}
return res;
}
int main(){
cin >> n;
fir(i,0,n-1){
fir(j,0,n-1){
cin >> mp[i*n+j].sd;
mp[i*n+j].ft = get(i,j);
}
}
sort(mp,mp+n*n);
int m = n*n;
int v=mp[0].sd,k=1;
fir(i,1,m-1){
if(mp[i].sd == mp[i-1].sd){
k++;
}
else{
cout << v << ","<<k << " ";
v = mp[i].sd;
k = 1;
}
}
cout << v << "," << k ;
return 0;
}
O题没考虑过别的解法,一眼看过去就是石子合并的变化题.区间dp模板题吧…用前缀和预处理一下就ok了
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 1e2+10;
const int mod = 9901;
const LL INF = 1e15;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
LL a[N];
LL dp[N][N];
int n;
LL dfs(int i,int j){
if(i == j) return dp[i][j] = 0;
if(dp[i][j] != INF) return dp[i][j];
for(int k=i;k<j;++k){
LL s1 = a[k]-a[i-1],s2 = a[j]-a[k];
dp[i][j] = min(dp[i][j],dfs(i,k)+dfs(k+1,j)+s1*s2);
}
return dp[i][j];
}
int main(){
while(cin >> n){
fir(i,1,n){
fir(j,1,n){
dp[i][j] = 1e15;
}
}
fir(i,1,n){
cin >> a[i];
a[i] += a[i-1];
}
cout << dfs(1,n) << endl;
}
return 0;
}
P题一眼dp题吧…今天a开门的话就能从昨天b.c.d里面开门的状态转移过来.没开门的话随便转移.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int dp[N][4];
int a[5];
int main(){
int n;
cin >> n;
fir(i,1,n){
fir(j,1,4){
cin >> a[j];
if(a[j]){
fir(k,1,4){
if(k == j) continue;
dp[i][j] = max(dp[i][j],dp[i-1][k]+1);
}
}
else{
fir(k,1,4){
dp[i][j] = max(dp[i][j],dp[i-1][k]);
}
}
}
}
int ans= 0;
fir(i,1,4){
ans = max(ans,dp[n][i]);
}
cout << ans;
return 0;
}
Q题…斐波那契数列…甚至longlong都不用开.
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
int f[N];
int main(){
int n;
f[1] = 1;
f[2] = 2;
fir(i,3,37){
f[i] = f[i-1]+f[i-2];
}
while(cin >> n){
cout << f[n] << endl;
}
return 0;
}
R题.想的脑壳都疼了还是没想到怎么转移.考虑过组合数学去解.还是把脑壳想疼了也不会.两点写完14题之后从22名到结束还是14题掉到了106名.都是泪orz
代码
无
S题看到前缀balabala的应该脑子里第一闪烁的就是trie树了(相信我,只要学过一定想得到).不过还有扩展就是怎么找以s为前缀的所有字符串.考虑字典树的结构.其实就是一个很明显dfs的问题.看代码好理解.
代码
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
const int mod = 9901;
LL gcd(LL a,LL b){return b == 0 ? a : gcd(b,a%b);}
set<string> u;
int trie[N][26],cnt=1,ed[N];
vector<string> vec;
bool f= 0;
void dfs(string s,int p){
if(!p) return;
if(vec.size() >= 50) return;
fir(i,0,25){
if(trie[p][i]){
f=1;
string tmp = s+char('a'+i);
if(ed[trie[p][i]]) vec.pb(tmp);
dfs(tmp,trie[p][i]);
}
}
}
int main(){
int n,q;
string s;
cin >> n;
fir(i,1,n){
cin >> s;
if(u.count(s)) continue;
u.insert(s);
int p = 1;
fir(j,0,s.size()-1){
int ch = s[j]-'a';
if(!trie[p][ch]) trie[p][ch] = ++cnt;
p = trie[p][ch];
}
ed[p] = 1;
}
cin >> q;
while(q--){
cin >> s;
int p = 1;
vec.clear();
fir(j,0,s.size()-1){
int ch = s[j]-'a';
if(!trie[p][ch]) trie[p][ch] = ++cnt;
p = trie[p][ch];
}
vec.pb(s);
f=0;
dfs(s,p);
if(!f) ed[p] = 1;
sort(vec.begin(),vec.end());
int si = vec.size();
si = min(si,50);
fir(i,0,si-1){
cout << vec[i] << endl;
}
}
return 0;
}