UESTC 1019 SSRaligun酱的魔法符文 用记忆实际区间最左min1最右max1来减小时间复

用记忆实际区间最min1最右max1,来减小时间复杂度    但注意min1要初始化为里面可能的最大值或比最大值大一点,而max1则是最小值或比最小值小一点,这些也是要注意的吧,不小心漏掉,到时候出问题又要找bug。

       也让自己意识到了else if 重叠用的时候该注意的(程序中打★★的地方)。


SSRaligun酱的魔法符文

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit  Status

打dota总是在蓝猫与小鹿之间纠结不清的SSRaligun酱是学院都市里一名隐藏的 level5 能力者,他会使用 3 种基本魔法符文,并且能够制作多种魔法

卷轴。在学院都市那终日不见阳光的ACM(Arch Chain Master)街上,SSRaligun酱拥有一家名叫秋之月的魔法卷轴商店。

不同的魔法卷轴需要不同的制作方法,所以制作一个魔法卷轴是很困难的,但是SSRaligun酱拥有一部如何制作魔法卷轴的秘术之书。(传说是一位

名为Icerain94的顶级能力者赠送给SSRaligun酱的禁书)秘术之书通常把魔法卷轴视作为一个 1×n  的矩阵(从 1 开始编号),然后执行 m 次填充操作,

每次操作在 [l,r]     的区间上填充第 type  种魔法符文。

在魔法填充结束之后如果同一格被填入了多种符文,符文就会互相融合,形成新的符文,符文合成公式如下:

type1+type1=type1 type2+type2=type2 type3+type3=type3
type1+type2=type4 type4+type1=type4 type4+type2=type4
type1+type3=type5 type5+type1=type5 type5+type3=type5
type2+type3=type6 type6+type2=type6 type6+type3=type6
type4+type4=type4 type5+type5=type5 type6+type6=type6
type4+type3=type7 type5+type2=type7 type6+type1=type7
type4+type5=type7 type4+type6=type7 type5+type6=type7
type1+type2+type3=type7 type4+type5+type6=type7
type7+type1=type7 type7+type2=type7 type7+type3=type7
type7+type4=type7 type7+type5=type7 type7+type6=type7
type7+type7=type7

温馨提示:上述公式可以总结为基础符文形成二阶符文,二阶符文形成三阶符文,同属性高阶符文吸收低阶符文,同属性同阶符文吸收同阶符文。

(相信我,理解这段话将大大缩短你的解题时间,而理解这些公式的内涵比你手工模拟公式的代码量要小很多)

现在我们知道了制作某个魔法卷轴所需要的 m 次步骤 l,r    和 type ,又萌又帅又可爱的SSRaligun酱一眼就看出了最后哪一种魔法符文的数量会最多,

那么现在你能算出这种魔法符文是那种魔法符文吗?

Input

第一行为数据组数 T ,对于每一组数据,第一行为两个整数 n,m(0<n,m2000) ,

接下来 m 行每行共有三个整数 l,r,type(1lrn,1type3) ,           分别表示魔法填充区域的左边界和魔法填充区域的右边界以及

对应魔法符文种类.

Output

对于每一组数据输出一行,每一行行首为Case+#标号,然后输出数量最多的魔法符文的 type  (如果有多种符文数量都是最多的,则按照数字编号从

小到大依次输出,详细见样例)。

Sample input and output

Sample Input Sample Output
2
6 3
1 3 3
1 2 2
1 1 1
10 2
1 5 2
6 10 3
Case #1: type3 type6 type7
Case #2: type2 type3

My Solution

总结出那个框框里的东西,然后就好了,反正只有0、7种情况
1可以+2、+3
2可以+3
3可以+4
4可以+5、+6
5可以+6、+2、+4
6可以+1
且L[ i ] += b+1;并且L[ i ] <= 7
具体请看下面的solve(,)函数了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2000+8;
int L[maxn];
int cot[9];

void solve(int i,int b)
{
    if(L[i]==0) L[i]=b;    //最开始的时候肯定是0了,所以讨论的时候这个不要漏掉
    else if(L[i]==7) ;
    else if(L[i]==6) {if(b==4||b==5||b==7||b==1) L[i]=7;}        //★★
    else if(L[i]==5) {if(b==6||b==4||b==2||b==7) L[i]=7;}        //★★
    else if(L[i]==4) {if(b==6||b==5||b==3||b==7) L[i]=7;}        //★★
    else if(L[i]==3) {if(b==4) L[i]=7;else if(b==2||b==1) L[i]+=b+1;else if(b==5||b==6||b==7) L[i]=b;}  //L[i]+=b+1
    else if(L[i]==2) {if(b==5) L[i]=7;else if(b==3||b==1) L[i]+=b+1;else if(b==4||b==6||b==7) L[i]=b;}
    else if(L[i]==1) {if(b==6) L[i]=7;else if(b==3||b==2) L[i]+=(b+1);else if(b==4||b==5||b==7) L[i]=b;}
}
int main()
{
    int T,n,m,l,r,type,min1,max1,ans,kase=0;   //关于最大值最小值的使用,要初始化对。。 及其记忆来减小复杂度
    scanf("%d",&T);
    while(T--){
        memset(L,0,sizeof(L));memset(cot,0,sizeof(cot));
        min1=n;max1=0;ans=0;                             //min1和max1的置零
        scanf("%d%d",&n,&m);
        while(m--){
            scanf("%d%d%d",&l,&r,&type);
            min1=min(min1,l);max1=max(max1,r);
            for(int i=l;i<=r;i++)
                solve(i,type);
        }
        for(int i=min1;i<=max1;i++)
            (cot[L[i]])++;//cout<<L[i]<<" ";
        for(int i=1;i<=7;i++)
               ans=max(ans,cot[i]);//cout<<cot[i]<<" ";}
        printf("Case #%d:",++kase);
        for(int i=1;i<=7;i++)
            {if(cot[i]==ans) printf(" type%d",i);}
        if(T) printf("\n");
    }
    return 0;
}

谢谢


你可能感兴趣的:(总结,ACM,ICPC,区间,OJ,uestc)