zoukankan      html  css  js  c++  java
  • 题解 POJ1964/UVA1330/SP277 【City Game】

    • 题目链接:
      https://www.luogu.org/problemnew/show/UVA1330
      http://poj.org/problem?id=1964
      https://www.luogu.org/problemnew/show/SP277

    • 思路:

      单调栈

      如果不知道这是什么可以先做这道题和看看本蒟蒻的博客:

      https://www.luogu.org/blog/Rye-Catcher/solution-sp1805

      或者到网上搜其他dalao的博客

      如果你知道单调栈的思路,那么就不难想了。

      刚刚链接里的那道题是在一根数轴上单调栈,那么在这道题中我的思路就是把每纵行看做一个数轴,以向右为正方向,数轴上每个横行对应每个点记录从这开始向右最多有几块空地(就好比是链接中矩形高度),用单调栈思路一根一根数轴的处理,不断更新最大值。

      单调栈具体实现跟链接中那道题几乎一样,唯一难题就是怎样预处理向右拓展的最多空地数,好吧其实这也不是最难之处。

      我们对于每一横行输入搞一个last记录上一个R的位置,先初始last=0,然后如果接下来在j处读到了一个R,就遍历last+1到j-1的空地,把下标为k(从1开始数第k个)的空地数赋值为j-k(在纸上画一画其实很容易理解),再把last设为j。注意,我们还要在越界处进行一次操作。

      如果上面看不懂就看代码吧,如果弄清链接那道题其实代码很好懂。

    • Tips:

      毒瘤输入 毒瘤输入 毒瘤输入

      搞这输入跟我从想题到打完代码时间一样长。

      POJ discuss区中甚至有人反映数据输出可能不严格按照要求(例如:两个字符间有多个空格)建议用cin读入。

    • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <cctype>
    #include <algorithm>
    #define ri register int 
    using namespace std;
    int n,m,t,anss=0;
    int city[1010][1010];
    template <class T>inline void read(T &x){
    	x=0;char c;int neg=0;
    	while(!isdigit(c=getchar()))neg=c=='-';
    	x=c-48;
    	while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    	x=neg?-x:x;
    }
    inline int solve(int r){  //单调栈
    	int w[1005],s[1005],p,ans=0;
    	city[n+1][r]=p=0;
    	for(ri i=1;i<=n+1;i++){
    		if(city[i][r]>s[p]){
    			s[++p]=city[i][r];
    			w[p]=1;
    		}
    		else {
    			int wid=0;
    			while(s[p]>city[i][r]){
    				wid+=w[p];
    				ans=max(ans,wid*s[p]);
    				p--;
    			}
    			if(city[i][r])s[++p]=city[i][r],w[p]=wid+1;
    		}
    	}
    	return ans;
    }
    int main()
    {
    	char ch;string sp;
    	cin>>t;
    	while(t--){
    	    anss=0;
    		read(n),read(m);
    		for(ri i=1;i<=n;i++){
    			int last=0;     
    			for(ri j=1;j<=m;j++){
    			    cin>>sp;ch=sp[0]; //毒瘤输入
    			     if(ch=='R'){ 
    					for(ri k=last+1;k<j;k++){//预处理
    						city[i][k]=j-k;
    					}
    					last=j;
    				}
    				else if(j==m){//注意这个操作必不可少
    				    for(ri k=last+1;k<=j;k++){
    						city[i][k]=j-k+1;
    					}
    				}
    			}
    		//	putchar('
    ');
    		}
    		for(ri i=1;i<=m;i++){//注意n,m的区别
    			anss=max(anss,solve(i));
    		}
    		memset(city,0,sizeof(city));
    		cout<<anss*3<<endl;
    	}
    	return 0;
    }
    

    代码效率较高,不过我很佩服10ms,POJ0ms的大佬们

  • 相关阅读:
    Step by step Dynamics CRM 2013安装
    SQL Server 2012 Managed Service Account
    Step by step SQL Server 2012的安装
    Step by step 活动目录中添加一个子域
    Step by step 如何创建一个新森林
    向活动目录中添加一个子域
    活动目录的信任关系
    RAID 概述
    DNS 正向查找与反向查找
    Microsoft Dynamics CRM 2013 and 2011 Update Rollups and Service Packs
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/8719612.html
Copyright © 2011-2022 走看看