zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 081

    C - Make a Rectangle

    从大到小贪心即可。

    # include <bits/stdc++.h>
    using namespace std;
    map<int,int>m;
    int main()
    {
    	int n, a;
    	scanf("%d",&n);
    	while(n--) scanf("%d",&a), m[a]++;
    	int r=0, c=0;
    	for(auto i:m)
    		if(i.second>3) r=c=i.first;
    		else if(i.second>1) c=r,r=i.first;
    	printf("%lld
    ",(long long)r*c);
    }
    
    

    D - Coloring Dominoes

    就是个乘法原理。

    # include <bits/stdc++.h>
    using namespace std;
    #define P 1000000007
    int n;
    char s1[100], s2[100];
    int main(){
    	scanf("%d%s%s",&n,s1,s2);
    	long long ans=s1[0]==s2[0]?3:6;
    	for(int i=1; i<n; ++i){
    		if(s1[i-1]==s2[i-1]) ans=ans*2%P;
    		if(s1[i]!=s2[i]&&s1[i-1]!=s2[i-1]&&s1[i]!=s1[i-1]&&s2[i]!=s2[i-1]) ans=ans*3%P;
    	}
    	printf("%lld",ans);
    }
    

    E - Don't Be a Subsequence

    首先考虑如何求答案串的最小长度。
    显然是可以dp的。
    首先考虑长度为1的答案,显然标记一下哪些字母没出现过即可。
    否则令(dp[i])表示(suffix(i))的以(s[i])为开头的答案串的最小长度,容易得到(dp[i]=min(dp[j]+1)),其中(j>i)并且(s[j])(suffix(i))里所有同样字符的最左端。
    对于每个(i),这样的j最多只有26个,可以通过一次(O(26 imes len))预处理出来。
    如果求出了答案串的最小长度,如何确定答案串的最小字典序呢?
    考虑dp转移的过程,每次用字典序靠前的字符来进行转移就行了。
    记录一下路径,倒序输出即可。
    时间复杂度(O(26 imes len))

    # include <bits/stdc++.h>
    using namespace std;
    const int N=200005;
    int vis[26];
    char s[N];
    struct Node{int len, id, c;}dp[N], ans;
    
    int main ()
    {
        scanf("%s",s+1);
        int len=strlen(s+1);
        for (int i=len; i>=1; --i) {
            dp[i].len=dp[vis[0]].len+1; dp[i].id=vis[0]; dp[i].c=0;
            for (int j=1; j<=25; ++j) if (dp[i].len>dp[vis[j]].len+1) dp[i].len=dp[vis[j]].len+1, dp[i].id=vis[j], dp[i].c=j;
            vis[s[i]-'a']=i;
        }
        for (int i=0; i<=25; ++i) if (!vis[i]) {printf("%c
    ",i+'a'); return 0;}
        ans.len=dp[vis[0]].len; ans.id=vis[0]; ans.c=0;
        for (int i=1; i<=25; ++i) if (ans.len>dp[vis[i]].len) ans.len=dp[vis[i]].len, ans.id=vis[i], ans.c=i;
        while (ans.id) putchar(ans.c+'a'), ans.c=dp[ans.id].c, ans.id=dp[ans.id].id;
        putchar(ans.c+'a');
        putchar('
    ');
        return 0;
    }
    

    F - Flip and Rectangles

    我们首先考虑一个(2 imes 2)的方格,如果包含奇数个黑格子的话,我们把它称为(Bad-Part)
    显然,对于每一个最后可能出现的黑矩形,其中必然不包含(Bad-Part)
    因为对于(Bad-Part),无论怎么操作都无法全部变黑。
    假设(S)不包含任意(Bad-Part),那么我们可以进行一些操作使得S全部变黑。
    如何证明?
    考虑S的最上面一行和最左边一行,由于我们必然要把他们变成黑色,所以操作是一定的,而这些操作也一定可以将
    整个S变黑。
    现在的问题是,找到一个面积最大的(S),使得S不包含任何(Bad-Part)
    我们可以把每个(Bad-Part)缩到(2 imes 2)方格中心的那个位置,我们把这样的点称为(Bad-Point)
    那么问题就变成了经典的最大全0子矩阵了。
    而这个问题有经典的悬线法可以(O(nm))解决。

    # include <bits/stdc++.h>
    using namespace std;
    const int N=2005;
    char s[N][N];
    int n, m, a[N], b[N];
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	int ans=max(n,m);
    	for(int i=0;i<n;i++) scanf("%s",s[i]);
    	for(int i=0;i<n;i++) {
    		for(int j=0;j<m-1;j++) {
                if(i&&!(s[i-1][j+1]^s[i][j]^s[i-1][j]^s[i][j+1])) a[j]++;
                else a[j]=1;
    		}
    		int t=0;
    		for(int j=0;j<=m-1;j++) {
    			while(t&&a[b[t-1]]>=a[j]) {
    				int x=b[--t];
    				if(t==0) ans=max(ans,(j+1)*a[x]);
    				else ans=max(ans,(j-b[t-1])*a[x]);
    			}
    			b[t++]=j;
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Mysql-学习笔记(==》事件 十二)
    Mysql-学习笔记(==》触发器 十一)
    Mysql-学习笔记(==》函数的建立与使用 十)
    Mysql-学习笔记(==》存储过程 九)
    Mysql-学习笔记(==》常用函数 八)
    Mysql-学习笔记(==》增删主键建立索引 七)
    Mysql-学习笔记(==》约束 六)
    Mysql-学习笔记(==》集合函数与分组四)
    Mysql-学习笔记(==》连接查询_高级查询五)
    Unity3D优化技巧系列七
  • 原文地址:https://www.cnblogs.com/lishiyao/p/7401910.html
Copyright © 2011-2022 走看看