前言:
div3的题相对来说比div1,div2好做了不是一点两点,可惜赛时没把e调出来,快结束才想到可以用二维差分来直接模拟。哎,我真傻,真的。
正文:
链接:Dashboard - Codeforces Round 966 (Div. 3) - Codeforces
A. Primary Task:
#include<bits/stdc++.h>
using namespace std;
int sizen(int x){
int cnt=0;
while(x){
x/=10;cnt++;
}
return cnt;
}
int main(){
int t;
cin>>t;
while(t--){
int a;
cin>>a;
int cnt=sizen(a);
if(cnt<=2){
cout<<"NO"<<endl;continue;
}
int x=a/pow(10,cnt-2);
int y=a-x*pow(10,cnt-2);
if(x==10&&sizen(y)==cnt-2&&y!=1){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}
取前两位和后面所有位在一一判断即可。
B. Seating in a Bus:
#include<bits/stdc++.h>
using namespace std;
int a[200005];
int b[200005];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
memset(b,false,sizeof(b));
for(int i=1;i<=n;i++)cin>>a[i];
bool flag=false;
for(int i=1;i<=n;i++){
if(i==1){
b[a[i]]=1;
}
else{
if(b[a[i]-1]==0&&b[a[i]+1]==0){
flag=true;
break;
}
b[a[i]]=1;
}
}
if(flag){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
}
}
return 0;
}
每次输入后将左右两点标记,若下次输入数所在位置未被标记,则输出 NO, 第一次输入特判即可
C. Numeric String Template:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[200005];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
a[i]+=1000000001;
}
int m;
cin>>m;
while(m--){
string s;
cin>>s;
map<char,int> mp;
map<int,char> mp2;
int l=s.size();int flag=0;
if(l!=n){
cout<<"NO"<<endl;
continue;
}
for(int i=0;i<l;i++){
if(mp[s[i]]==0&&mp2[a[i]]==0){
mp[s[i]]=a[i];
mp2[a[i]]=s[i];
}
else{
if(mp[s[i]]==a[i]&&mp2[a[i]]==s[i])continue;
else{
flag=1;
break;
}
}
}
if(flag){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
}
}
}
return 0;
}
题意类似函数的定义,要求数字与字符一一对应,这边我们直接用两个map来对应如果出现矛盾情况直接输出no。
D. Right Left Wrong:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[200005];
ll pre[200005];
int main(){
int t;
cin>>t;
while(t--){
int n;ll ans=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];pre[i]=pre[i-1]+a[i];
}
string s;
cin>>s;
int l=0,r=n-1;
while(l<r){
while(s[l]!='L'&&l<r)l++;
while(s[r]!='R'&&l<r)r--;
if(l<r)ans+=pre[r+1]-pre[l];
l++;r--;
}
cout<<ans<<endl;
}
return 0;
}
逆向思维,我们先从最外层开始考虑,用对撞指针来模拟过程同时更新答案。
E. Photoshoot for Gorillas:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve(){
ll n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
ll w;
scanf("%lld",&w);
vector<ll> a(w+1);
for(int i=1;i<=w;i++){
scanf("%lld",&a[i]);
}
sort(a.begin()+1,a.end());
ll d[n+k+1][m+k+1];
memset(d,0,sizeof(d));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
ll x2=i+k-1,y2=j+k-1;
if(x2>n or y2>m)
continue;
d[i][j]++;
d[i][y2+1]--;
d[x2+1][j]--;
d[x2+1][y2+1]++;
}
}
priority_queue<ll> q;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
d[i][j]+=d[i-1][j]+d[i][j-1]-d[i-1][j-1];
q.push(d[i][j]);
}
}
ll ans=0;
for(int i=w;i>=1 and !q.empty();i--){
ans+=q.top()*a[i];
q.pop();
}
printf("%lld\n",ans);
}
int main(){
int t=1;
scanf("%d",&t);
while(t--){
solve();
}
return 0;
}
用差分来计算地图不同位置的景观值,类似与对一个矩阵内所有点加一的重复操作。我们将矩阵内所有点的值存入大根堆内,并取队首与当前最高的猩猩相乘加入答案,最后输出即可。
后记:
剩下的题我依旧时看看别人的题解看看能不能补吧。