这是第一次,我打算一直每次选3个题(提高+/省选-),看最后多少分(第一次交),今天算是10+70+30=110,真的好低。。
T1
这题其实挺简单,树状数组&&二分,然后我就写炸了,10分,唉,真无语,然后看了题解,发现这题还可以set来做,不过是逆向思维。
代码1:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
using namespace std;
inline int lowbit(int x){
return x&-x;
}
int n,m;
int t[50001];
inline int query(int x){
int sum=0;
while(x){
sum+=t[x];
x-=lowbit(x);
}
return sum;
}
inline void update(int x,int v){
while(x<=n){
t[x]+=v;
x+=lowbit(x);
}
}
int solve(int x){
if(query(x)-query(x-1)==0){
return 0;
}
int l=1,r=x;
int mid;
while(l<r){
mid=(l+r)>>1;
if(query(mid)-query(l-1)==mid-l+1){
l=mid+1;
}
else{
r=mid;
}
}
int sum=0;
if(query(x)==x){
sum+=x;
}
else{
sum+=x-l;
}
l=x,r=n;
while(l<r){
mid=(l+r)>>1;
if(query(mid)-query(l-1)==mid-l+1){
l=mid+1;
}
else{
r=mid;
}
}
if(query(n)-query(x-1)==n-x+1){
sum+=n-x;
}
else{
sum+=l-x-1;
}
return sum;
}
stack<int> s;
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
update(i,1);
}
for(int i=1;i<=m;i++){
char ch;
cin>>ch;
if(ch=='D'){
int x;
scanf("%d",&x);
update(x,-1);
s.push(x);
}
else if(ch=='R'){
int x=s.top();
s.pop();
update(x,1);
}
else{
int x;
scanf("%d",&x);
printf("%d
",solve(x));
}
}
return 0;
}
代码2:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#define ll long long
using namespace std;
set<int> s;
int n,m;
stack<int> q;
int main(){
scanf("%d %d",&n,&m);
s.insert(0);
s.insert(n+1);
for(int i=1;i<=m;i++){
char ch;
cin>>ch;
if(ch=='D'){
int x;
scanf("%d",&x);
s.insert(x);
q.push(x);
}
else if(ch=='R'){
int x;
x=q.top();
q.pop();
s.erase(s.find(x));
}
else{
int x;
scanf("%d",&x);
set<int>::iterator it=s.lower_bound(x);
if(*it==x){
printf("0
");
continue;
}
int num=*it-*(--it)-1;
printf("%d
",num);
}
}
return 0;
}
T2
这题首先想搜索,然后就看见你n<=16,果断状压dp,然后就又写挂了,70分,看了题解之后,发现少了一维状态,加上就A了,才感觉自己智障了。。
代码1:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
int n;
char a[20][101];
int len[20];
int g[20][20];
int f[1000001];
int main(){
scanf("%d",&n);
int all=1<<n;
int ans=0;
for(int i=1;i<=n;i++){
scanf("%s",a[i]);
len[i]=strlen(a[i]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][len[i]-1]==a[j][0]){
g[i][j]=1;
}
}
}
for(int i=1;i<=n;i++){
f[1<<(i-1)]=len[i];
}
for(int s=0;s<all;s++){
for(int i=1;i<=n;i++){
if((s>>(i-1))&1){
for(int j=1;j<=n;j++){
if(!((s>>(j-1))&1)){
if(g[i][j]){
f[s+(1<<(j-1))]=max(f[s+(1<<(j-1))],f[s]+len[j]);
}
}
}
}
}
ans=max(ans,f[s]);
}
printf("%d",ans);
return 0;
}
代码2:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
int n;
char a[20][101];
int len[20];
int g[20][20];
int f[20][500001];
int main(){
scanf("%d",&n);
int all=1<<n;
int ans=0;
for(int i=1;i<=n;i++){
scanf("%s",a[i]);
len[i]=strlen(a[i]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][len[i]-1]==a[j][0]){
g[i][j]=1;
}
}
}
for(int i=1;i<=n;i++){
f[i][1<<(i-1)]=len[i];
}
for(int s=0;s<all;s++){
for(int i=1;i<=n;i++){
if((s>>(i-1))&1){
for(int j=1;j<=n;j++){
if(!((s>>(j-1))&1)){
if(g[i][j]){
f[j][s+(1<<(j-1))]=max(f[j][s+(1<<(j-1))],f[i][s]+len[j]);
}
}
}
ans=max(ans,f[i][s]);
}
}
}
printf("%d",ans);
return 0;
}
T3
这题是我选的最后一题,一看题,多重背包呀,裸题,然后准备写。我就想,先看看数据范围吧,好开数组,就看见数据范围大得要命,这题算部分30分吧,虽然没写(滑稽),一会儿写了这个题再来补上吧。。