/** 鼠标样式 **/

Shu-How Zの小窝

Loading...

AtCoder Beginner Contest 366

AtCoder Beginner Contest 366题解

A - Election 2

题意:

n张票,目前投了t给高桥, a 给青木。
问剩余票随便分配,是否都是一个结局。

思路:

将剩下的票全都给同一个人,看看是否局面发生变化

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+100,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
void solve()
{
  int a,b,c;
  cin>>a>>b>>c;
  if(b>a-b||c>a-c) cout<<"Yes"<<endl;
  else cout<<"No"<<endl;
}
signed main()
{
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    T=1;
    //cin>>T;99 12 48

    while(T--)
     {
         solve();
     }
     return 0;
} 

B - Vertical Writing

题意:

给定n个字符串,把这 n个字符串顺时针旋转90度,输出。
由于字符串长度不一,可能会出现空的情况,前面的 都要替换成*

思路:

先将字符串翻转90°,然后记录一下每一行最后一个字符的位置end,在end前的位置如果存在空,则要替换为*

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+100,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
int n;
char op[1010][1010];
int ba[N];
void solve()
{
   cin>>n;
   for(int i=1;i<=110;i++)
   	for(int j=1;j<=110;j++)
   		op[i][j]='*';
   	int mx=0;
   for(int i=1;i<=n;i++)
   {
   	string kk;
   	cin>>kk;
   	mx=max(mx,(int)kk.size());
   	for(int j=0;j<kk.size();j++) op[i][j+1]=kk[j];
   }
   for(int i=1;i<=mx;i++)
   {
   	for(int j=n;j>=1;j--)
   	{
   		if(op[j][i]!='*') ba[i]=j;
   	}
   }
   for(int i=1;i<=mx;i++)
   {
   	for(int j=n;j>=ba[i];j--) cout<<op[j][i];
   	cout<<endl;
   }
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    T=1;
    //cin>>T;99 12 48
    while(T--)
     {
         solve();
     }
     return 0;
} 

C - Balls and Bag Query

题意:

q个操作,分三种。

  • 1 x 放入背包一个球,数字x
  • 2 x 从背包拿出一个球,数字x
  • 3 问背包不同数字球的个数

思路:

模拟即可

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
bool st[N];
int cnt[N];
int ans=0;
void solve()
{
    int q;
    cin>>q;
    memset(cnt,0,sizeof cnt);
    memset(st,false,sizeof st);
    while(q--)
    {
        int id;
        cin>>id;
        if(id==1)
        {
            int x;
            cin>>x;
            if(!st[x])
            {
                st[x]=true;
                cnt[x]++;
                ans++;
            }
            else
            {
                cnt[x]++;
            }
        }
        else if(id==2)
        {
            int x;
            cin>>x;
            if(cnt[x]==1)
            {
                cnt[x]=0;
                st[x]=false;
                ans--;
            }
            else
            {
                cnt[x]--;
            }
        }
        else
        {
            cout<<ans<<endl;
        }

    }
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    T=1;
    //cin>>T;
    while(T--)
     {
         solve();
     }
     return 0;
} 

D - Cuboid Sum Query

题意:

给定一个正整数 N,以及一个整数 Ax,y,z,对于每组三个整数 (x,y,z),满足 1x,y,zN

将给出 Q 个查询,格式如下,必须按顺序处理。

对于第 i 个查询 (1iQ),给定一个整数元组 (Lxi,Rxi,Lyi,Ryi,Lzi,Rzi),使得 1LxiRxiN1LyiRyiN1LziRziN。求:

x=LxiRxiy=LyiRyiz=LziRziAx,y,z

思路:

三维区间求和,考验空间想象能力。
前缀和表达式
s[i][j][k]=s[i][j][k1]+s[i][j1][k]+s[i1][j][k]s[i1][j1][k]s[i1][j][k1]s[i][j1][k1]+s[i1][j1][k1]+f[i][j][k]
(x1,x2,y1,y2,z1,z2)区间的和为
s[x2][y2][z2]s[x11][y2][z2]s[x2][y11][z2]s[x2][y2][z11]+s[x2][y11][z11]+s[x11][y2][z11]+s[x11][y11][z2]s[x11][y11][z11]

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+10,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
int n,q;
int f[110][110][110];
int s[110][110][110];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int h=1;h<=n;h++)
                cin>>f[i][j][h];
    memset(s,0,sizeof s);
    for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=1;k<=n;k++)
    {
        s[i][j][k]=s[i][j][k-1]+s[i][j-1][k]+s[i-1][j][k]-s[i-1][j-1][k]+f[i][j][k]-s[i-1][j][k-1]-s[i][j-1][k-1]+s[i-1][j-1][k-1];
    }
    cin>>q;
    while(q--)
    {
        int x1,x2,y1,y2,z1,z2;  
        cin>>x1>>x2>>y1>>y2>>z1>>z2;
        int ans=s[x2][y2][z2]-s[x1-1][y2][z2]-s[x2][y1-1][z2]-s[x2][y2][z1-1]+s[x2][y1-1][z1-1]+s[x1-1][y2][z1-1]+s[x1-1][y1-1][z2]-s[x1-1][y1-1][z1-1];
        cout<<ans<<endl;
    }
    
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    T=1;
    //cin>>T;
    while(T--)
     {
         solve();
     }
     return 0;
} 

E - Manhattan Multifocal Ellipse

题意:

给定 n 个二维平面上的点 (x1,y1),(x2,y2),,(xn,yn) 和一个非负整数 D,我们需要计算满足以下条件的整数对 (x,y) 的数量:
i=1n(|xxi|+|yyi|)D

思路:

可以发现x,y坐标是相互独立的,所以我们可以分开处理:对每一个坐标上[2e6,2e6]上的点xk,我们可以二分预处理出i=1n(|xkxi|)的值,找到第一个比它大的点xa,那么i=1n(|xkxi|)=i=1a1(xaxi)+i=an(xixa),记为ra[i].将得到的值进行排序,要求ra+rb<=D的个数,可以双指针O(n)求出.

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
int n,d;
int x[N],y[N];
int sa[N];
int sb[N];
vector<int> ra;
vector<int> rb;
void solve()
{
  cin>>n>>d;
  for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
  sort(x+1,x+1+n);
  sort(y+1,y+1+n);
  sa[0]=sb[0]=0;
  for(int i=1;i<=n;i++) sa[i]=sa[i-1]+x[i],sb[i]=sb[i-1]+y[i];
  for(int i=-2e6;i<=2e6;i++)
  {
    int l=0,r=n+1;
    while(l+1!=r)
    {
        int mid=(l+r)/2;
        if(x[mid]>i) r=mid;
        else l=mid;
    }
    int p=(2*l-n)*i+sa[n]-sa[l]-sa[l];
    ra.push_back(p);
  }
  for(int i=-2e6;i<=2e6;i++)
  {
    int l=0,r=n+1;
    while(l+1!=r)
    {
        int mid=(l+r)/2;
        if(y[mid]>i) r=mid;
        else l=mid;
    }
    int p=(2*l-n)*i+sb[n]-sb[l]-sb[l];
    rb.push_back(p);
  }
  sort(ra.begin(),ra.end());
  sort(rb.begin(),rb.end());
  int j=rb.size()-1;
  int ans=0;
  for(auto i : ra)
  {
    while(j>=0)
    {
        if(i+rb[j]>d) j--;
        else
        {
            ans+=(j+1);
            break;
        }
    }
    if(j<0) break;
  }
  cout<<ans<<endl;
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    T=1;
    //cin>>T;
    while(T--)
     {
         solve();
     }
     return 0;
} 

F - Maximum Composition

题意:

给定N个线性函数f1,f2,...,fn,其中fi(x)=Aix+Bi
求最大的fp1(fp2(...fpk(1)...))

思路:

只考虑两个函数f1f2:f1=a1x+b1f2=a2x+b2,如何选择位置使得值最大。
f1(f2(1))=a1(a2+b2)+b1=a1a2+a1b2+b1
f2(f1(1))=a2(a1+b1)+b2=a2a1+a2b1+b2
假设f1(f2(1))<f2(f1(1)),那么有a1b2+b1<a2b1+b2,整理得a11b1<a21b2
即如果ai1bi更大,我们就考虑把它放在外面。所以我们可以对ai1bi排序,从n个函数中取出k个,使得值最大,类似于01背包的写法

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10,mod=998244353;
typedef long long ll;
typedef pair<int,int> PII;
int T;
int n,k;
struct node
{
  int a;
  int b;
}x[N];
bool cmp(node x,node y)
{
   return (y.a-1)*x.b>(x.a-1)*y.b;
}
int dp[N];
void solve()
{
  cin>>n>>k;
  for(int i=1;i<=n;i++) cin>>x[i].a>>x[i].b;
  sort(x+1,x+1+n,cmp);
  dp[0]=1;
  for(int i=1;i<=n;i++)
  {
    for(int j=k;j>=1;j--)
    {
        dp[j]=max(dp[j],x[i].a*dp[j-1]+x[i].b);
    }
  }
  cout<<dp[k]<<endl;
}
signed main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    T=1;
    //cin>>T;
    while(T--)
     {
         solve();
     }
     return 0;
} 

G - XOR Neighbors

题意:

思路:

代码:

posted @   Violet_fan  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示