• CF611F New Year and Cleaning


    题意

    CF611F New Year and Cleaning

    想法

    这个题是(NOIP2020)的弱化版。。

    我们把所有在二维上的点都一起考虑,那么所有点对于一个步骤的移动是相当于这些所有点所组成的矩形在移动。

    黑色的是我们的规定区域,蓝色的是我们所有二维的点的矩阵,可以看出对于每一步所出界的贡献我们是可以用这个超出的矩形面积来算的。

    我们在移的过程中,维护现在这个矩形的左上和右下的端点就可以解决,超界就拉回来。

    但是我们发现有些点是会走很多很多很多轮的,复杂度代价太高。

    这里建议读者手玩几组样例,我们会发现,除了第一次的计算外,第二第三轮,在每一步所出界的边是一样的。

    所以我们单独处理第一轮,第二轮,记录第二轮出界的边以及在第几轮出界,然后在第((n > 2))轮我们要维护的就是这个矩形的长宽了。

    可能代码会更加清晰一些。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    
    ll n,h,w;
    ll x1,x2,y1,y2;
    ll mod = 1e9 + 7;
    char s[1000005];
    
    void get(ll &x,ll &y,int k){
    	if(s[k] == 'U')y -- ;
    	if(s[k] == 'R')x ++ ;
    	if(s[k] == 'D')y ++ ;
    	if(s[k] == 'L')x -- ;
    } 
    
    ll ans = 0;
    
    ll c[1000005],e[1000005];
    
    int main(){
    	scanf("%lld%lld%lld",&n,&h,&w);
    	scanf("%s",s + 1);
    	ll k = strlen(s + 1);
    	x1 = 1,x2 = w,y1 = 1,y2 = h;
    	for(int i = 1;i <= k;++i){
    		get(x1,y1,i);
    		get(x2,y2,i);
    		if(x1 == 0&&x1 <= x2&&y1 <= y2)x1 = 1,ans = (ans + i * (y2 - y1 + 1) % mod) % mod;
    		if(x2 == w + 1&&x1 <= x2&&y1 <= y2)x2 = w,ans = (ans + i * (y2 - y1 + 1) % mod) % mod;
    		if(y1 == 0&&x1 <= x2&&y1 <= y2)y1 = 1,ans = (ans + i * (x2 - x1 + 1) % mod) % mod;
    		if(y2 == h + 1&&x1 <= x2&&y1 <= y2)y2 = h,ans = (ans + i * (x2 - x1 + 1) % mod) % mod;						
    	}
    	ll num = 0;
    	for(int i = 1;i <= k;++i){
    		get(x1,y1,i);
    		get(x2,y2,i);
    		if(x1 == 0&&x1 <= x2&&y1 <= y2)x1 = 1,ans = (ans + (i + n) * (y2 - y1 + 1) % mod) % mod,c[++num] = i,e[num] = 0;
    		if(x2 == w + 1&&x1 <= x2&&y1 <= y2)x2 = w,ans = (ans + (i + n) * (y2 - y1 + 1) % mod) % mod,c[++num] = i,e[num] = 0;
    		if(y1 == 0&&x1 <= x2&&y1 <= y2)y1 = 1,ans = (ans + (i + n) * (x2 - x1 + 1) % mod) % mod,c[++num] = i,e[num] = 1;
    		if(y2 == h + 1&&x1 <= x2&&y1 <= y2)y2 = h,ans = (ans + (i + n) * (x2 - x1 + 1) % mod) % mod,c[++num] = i,e[num] = 1;						
    	}
    	if(!num && x1 <= x2 && y1 <= y2){puts("-1");return 0;}
    	for (ll nw=2,x=x2-x1+1,y=y2-y1+1;x>0&&y>0;nw++)
    		for (int i=1;i<=num;i++) 
    		{
    			if (e[i] == 1&&x>0&&y>0) ans = (ans + std::max(x,0ll)*(nw * n % mod + c[i]) % mod) % mod,y--;
    			if (e[i] == 0&&x>0&&y>0) ans = (ans + std::max(y,0ll)*(nw * n % mod + c[i]) % mod) % mod,x--;
    		}
    	std::cout<<ans % mod;
    }
    
  • 相关阅读:
    开源介绍:Google Guava、Google Guice、Joda-Time
    Java开发必用的工具包
    GitHub vs GitLab:它们有什么区别?
    ELK简单使用
    Sublime Text 2 快捷键大全
    跨域iframe高度自适应(兼容IE/FF/OP/Chrome)
    关于jQuery新的事件绑定机制on()的使用技巧
    指尖上的正则表达式–入门篇
    淘宝商城文本输入框效果模仿
    纯CSS打造Flow-Steps导航
  • 原文地址:https://www.cnblogs.com/dixiao/p/14281632.html
Copyright © 2020-2023  润新知