2023牛客暑期多校第四场题解(L,A)

A-Bobo String Construction

题意

给一个字符串t和整数n,让你构造一个长度为n的字符串s,满足t+s+t这个新的字符串除了开头和结尾的之外不能再出现字符串t。

题解

由题意可以看出构造一个全0串或者一个全1串即可。

定义一个长度为n全0的字符串p。让s=t+p+t,然后利用find函数和substr函数查找s中有多少个子串t,如果是两个,则说明全0字符串p是满足条件的,输出p,否则输出一个长度为n的全1字符串。

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long 
ll i;

ll solve(string s,ll n,string t)
{
    ll sum=0;
    for(i=0;i<s.size();i++)
    {
        if(s.substr(i,n)==t)
            sum++;
    }
    return sum;
}

int main()
{
    ll T,n;
	string t;
    cin>>T;
    while(T--)
    {
        cin>>n;
        cin>>t;
        string p,q;
        for(i=0;i<n;i++)
        {
            p+='0';
            q+='1';
        }
        string s=t+p+t;
        ll a=t.size();
        if(solve(s,a,t)==2) cout<<p<<endl;
        else cout<<q<<endl;
    }
	return 0;
}

L-We are the Lights

题意

有n行m列的电灯矩阵,初始全为关闭状态

每次操作会打开或关闭某一行/列的所有灯

问在给定的 q 次操作后,共有多少盏灯亮着

题解

这题要倒着来进行模拟,大概的基本原理:对于某一行开关,假设它被进行了多次​更改,但是只要我知道它最后一次被执行了该行开灯的操作,那么这一行灯的状态就是开。
并且,由于我们是倒着模拟的,那么前面的操作就不能对后面的操作产生影响。
倒着操作的过程中,每次操作完一行,我就打标记,表示这行被操作过了,在倒着循环的过程中再遇到就可以跳过
要注意的是,不管开灯还是关灯,操作完这一行的状态就定死了,也就是说每次操作完都要更新行和列,就是n和m表示剩下的可以被操作的行和列。

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1e6+5;
struct node
{
	ll x,y,z;
};

// x记录行/列, y记录第几行/第几列, z记录开灯/关灯

node a[N];

ll f1[N],f2[N];  //f1用来标记行有没有被操作过,f2用来标记列

int main()
{
    ll n,m,q,sum,i;
    cin>>n>>m>>q;
    ll ans=0;
    for(i=1;i<=q;i++)                      //因为要倒着模拟,所以先存下来
    {
        string s1,s2;
        ll p;
        cin>>s1>>p>>s2;
        
        if(s1!="row")
        	a[i].x=1;        //a[i].x为0表示是行操作,为1表示为列操作。 
        
		a[i].y=p;            //a[i].y存第几行或者第几列。 
		
        if(s2=="on")
        {
            a[i].z=1;    //a[i].z为1表示是开,为0表示关。 
        }    
    }
    
    for(i=q;i>=1;i--)
    {
    	if(a[i].x==0) 
    	{
    		if(f1[a[i].y]) continue;   //被标记就跳过
            f1[a[i].y]=1; //防止重复加 
    		if(a[i].z)
    		{
    			ans+=m;   
            }
            n--;          //可开关行减一 (前面的操作会被后面覆盖,所有后面操作过了就不用管前面怎么变了)
		}
		else 
		{
			if(f2[a[i].y]) continue;
            f2[a[i].y]=1;
			if(a[i].z)
			{
				ans+=n;
            }
            m--;         //可开关列减一 
		}
	}
	cout<<ans;
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值