eg:弱智場,D題題意讀半天,差一分鐘就四題,B題也被關了好久,太久不訓練就會變傻啊。
比賽鏈接
A
題解:簽到題,考慮抽屜原理,統計A做出來B沒做出來的題爲cnt和A沒做出來B做出來的題爲sum,最後答案就是
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
int a[110],n,b[110];
int ans,cnt;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&b[i]);
for(int i=1;i<=n;i++)
if(a[i]==1 && b[i]==0)ans++;
else if(a[i]==0 && b[i]==1)cnt++;
if(!ans)puts("-1");
else printf("%d\n",(ans+cnt)/ans);
return 0;
}
B
題意:給出一個數組a,對於每一個元素,如果那麼就可以選擇,問怎麼選擇使得選擇的ai之和最大。
題解:移動一下那個等式可以發現,只要將所有的元素減去下標排序,相等的加起來比較取一個最大的即可。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
struct arr{
int val,no;
}a[maxn];
int n;
bool cmp(arr a,arr b){
return a.val>b.val;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i].val),a[i].no=i;;
for(int i=1;i<=n;i++)a[i].val-=i;
sort(a+1,a+1+n,cmp);
ll ans=0,sum=0;
for(int i=1;i<=n;i++){
if(a[i].val==a[i-1].val || i==1)
ans=ans+1ll*a[i].no+1ll*a[i].val;
else{
sum=max(ans,sum);
ans=a[i].no+a[i].val;
}
}
sum=max(sum,ans);
printf("%lld\n",sum);
return 0;
}
C
題意:給出一個字符串,每次可以刪除一個字母,被刪除的這個字母左右必須是該字母的前驅,問最多能刪多少個字母。
題解:從最大的字母到最小的字母刪。
#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
int n;
char s[maxn];
int vis[maxn],ans;
int main(){
scanf("%d",&n);
scanf("%s",&s);
char b='z';
while(true){
int flag=0;
char ch='a';
for(int i=0;i<n;i++){
if(!vis[i]){
if(s[i]>ch)ch=min(s[i],b);
}
}
for(int i=0;i<n;i++)
if(!vis[i] && ch==s[i]){
int l=i-1,r=i+1;
while(l>=0 && vis[l])l--;
while(r<n && vis[r])r++;
if(s[l]==s[i]-1 || s[r]==s[i]-1)vis[i]=1,flag=1,ans++;
}
if(!flag){
b=ch-1;
if(b<='a')break;
}
}
printf("%d\n",ans);
return 0;
}
D
題意:給出一個單向圖和一條路徑,現在問每次訪問的點是否是最短路,如果是其最短路條數是否唯一。
題解:讀題讀半天,從終點反向bfs到起點,再逐個檢查原路徑,如果該點不是最短路那麼第一種答案增加,如果當前點最短路條數不唯一第二種答案增加。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
int n,m,k;
int a[maxn],d[maxn],vis[maxn];
vector<int>G[maxn],V[maxn];
queue<int>q;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
G[v].push_back(u);
V[u].push_back(v);
}
scanf("%d",&k);
for(int i=1;i<=k;i++)scanf("%d",&a[i]);
int st=a[k],ed=a[1];
q.push(st);
d[st]=0,vis[st]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(vis[v])continue;
d[v]=d[u]+1;
q.push(v);
vis[v]=1;
}
}
int ans1=0,ans2=0;
for(int i=1;i<k;i++){
if(d[a[i]]!=d[a[i+1]]+1)ans1++;
for(int j=0;j<V[a[i]].size();j++){
int u=V[a[i]][j];
if(u!=a[i+1] && d[u]+1==d[a[i]]){
ans2++;
break;
}
}
}
printf("%d %d\n",ans1,ans2);
return 0;
}