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

来源:互联网 发布:网上认证发票软件 编辑:程序博客网 时间:2024/04/30 04:29

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

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


SSRaligun酱的魔法符文

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

打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=type3type1+type2=type4 type4+type1=type4 type4+type2=type4type1+type3=type5 type5+type1=type5 type5+type3=type5type2+type3=type6 type6+type2=type6 type6+type3=type6type4+type4=type4 type5+type5=type5 type6+type6=type6type4+type3=type7 type5+type2=type7 type6+type1=type7type4+type5=type7 type4+type6=type7 type5+type6=type7type1+type2+type3=type7 type4+type5+type6=type7type7+type1=type7 type7+type2=type7 type7+type3=type7type7+type4=type7 type7+type5=type7 type7+type6=type7type7+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 InputSample Output
26 31 3 31 2 21 1 110 21 5 26 10 3
Case #1: type3 type6 type7Case #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;}

谢谢


0 0