置换,循环,模拟(像素混合,LA 3510)

大模拟+置换理论

就是按要求把每个操作都实现一遍,然后常规的找循环节,然后答案显然是所有循环节的最小公倍数。


感觉自己写长代码,大模拟的能力很弱,主要是因为自己找小错误能力太弱(其实啥都弱),代码一长,更多的小细节会遗漏和出错,而自己却写得很爽并且浑然不知,然后连样例都过不了,还以为是思路或者方法出了问题,反复测试都找不到问题。


解决办法:大模拟这种东西是最考验踏实程度的题目了。首先要运筹帷幄,思考一下整个程序的框架,大概需要哪些功能,要用写哪些函数,会用哪些算法,可否实现以及如何实现。在一开始编写代码的时候,就应该小心翼翼,稳稳地去实现每一个细节,反复检查,极大地降低出错的可能性。写完后如果出现了问题,根据情况认真地检查每一个功能实现的细节或者整体的框架之间的协同。


上面提到了很多次要仔细。那是因为:

随便检查十遍不如认真检查一遍。


还要提一点,那就是:

带入样例+自编数据,然后一步一步跑也是一个不错的选择,优点是偷懒+快速找到思维死角,缺点是碰运气。


代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;

ll n;
ll vis[1100][1100];
vector<ll>op;

pll rot(pll a)
{
    return make_pair(n-a.second+1,a.first);
}

pll rot_(pll a)
{
    return make_pair(a.second,n-a.first+1);
}

pll sym(pll a)
{
    return make_pair(a.first,n-a.second+1);
}

pll vsm(pll a)
{
    return make_pair(n-a.first+n/2+1,a.second);
}

pll div(pll a)
{
    if(a.first&1) return make_pair((a.first+1)/2,a.second);
    else return make_pair(a.first/2+n/2,a.second);
}

pll div_(pll a)
{
    if(a.first<=n/2) return make_pair(a.first*2-1,a.second);
    else return make_pair(2*(a.first-n/2),a.second);
}

pll mix_(pll a)
{
    if(a.first&1) return make_pair(a.first+((a.second&1)?0:1),(a.second+1)/2);
    else return make_pair(a.first-((a.second&1)?1:0),n/2+(a.second+1)/2);
}

pll mix(pll a)
{
    if(a.second<=n/2) return make_pair(((a.first+1)/2)*2-1,2*a.second-((a.first&1)?1:0));
    else return make_pair(((a.first+1)/2)*2,2*(a.second-n/2)-((a.first&1)?1:0));
}

ll id(string s)
{
    if(s=="id") return 0;
    else if(s=="id-") return 0;
    else if(s=="rot") return 1;
    else if(s=="rot-") return 2;
    else if(s=="sym") return 3;
    else if(s=="sym-") return 3;
    else if(s=="bhsym") return 4;
    else if(s=="bhsym-") return 5;
    else if(s=="bvsym") return 6;
    else if(s=="bvsym-") return 7;
    else if(s=="div") return 8;
    else if(s=="div-") return 9;
    else if(s=="mix") return 10;
    else if(s=="mix-") return 11;
    else return -1;
}

ll gcd(ll a,ll b)
{
    return !b?a:gcd(b,a%b);
}

ll lcm(ll a,ll b)
{
    return a/gcd(a,b)*b;
}

ll dfs(pll s,pll c,ll d)
{
    vis[c.first][c.second]=1;
    if(d!=0&&s==c) return d;
    else
    {
        vis[c.first][c.second]=1;
        for(ll i=op.size()-1;~i;i--)
        {
            switch (op[i])
            {
            case 0:break;
            case 1:c=rot(c);break;
            case 2:c=rot_(c);break;
            case 3:c=sym(c);break;
            case 4:
            case 5:if(c.first>n/2)
                    {
                        c=sym(c);
                    }
                    break;
            case 6:
            case 7:
                    if(c.first>n/2)
                    {
                        c=vsm(c);
                    }
                    break;
            case 8:c=div(c);break;
            case 9:c=div_(c);break;
            case 10:c=mix(c);break;
            case 11:c=mix_(c);break;
            }
        }
        return dfs(s,c,d+1);
    }
}

ll a[25][25];

void init()
{
    for(ll i=1,j=n/2,J=n/2+1;i<=n;i++)
    {
        a[i][j]=a[i][J]=1;
        if((i&1)==0)
        {
            j--;
            J++;
        }
    }
    for(ll j=4;j<=17;j++)
        a[14][j]=1;
}

ll NEW[25][25];

void demo()
{
    for(ll i=1;i<=n;i++)
    {
        for(ll j=1;j<=n;j++)
        {
            pll temp=make_pair(i,j);
            ll num=8;
            while(num--)
            {
                temp=div(temp);
                temp=rot(temp);
                temp=div(temp);
                temp=rot_(temp);
            }
            NEW[temp.first][temp.second]=a[i][j];
        }
    }
    for(ll i=1;i<=n;i++)
    {
        for(ll j=1;j<=n;j++)
            if(NEW[i][j]) printf("1 ");
            else printf("  ");
        puts("");
    }
}

ll get(ll i,ll j)
{
    pll s=make_pair(i,j);
    pll c=s;
    ll d=0;
    while(d==0||s!=c)
    {
        vis[c.first][c.second]=1;
        for(ll k=op.size()-1;k>=0;k--)
        {
            switch (op[k])
            {
            case 0:break;
            case 1:c=rot(c);break;
            case 2:c=rot_(c);break;
            case 3:c=sym(c);break;
            case 4:
            case 5:if(c.first>n/2)
                    {
                        c=sym(c);
                    }
                    break;
            case 6:
            case 7:
                    if(c.first>n/2)
                    {
                        c=vsm(c);
                    }
                    break;
            case 8:c=div(c);break;
            case 9:c=div_(c);break;
            case 10:c=mix(c);break;
            case 11:c=mix_(c);break;
            }
        }
        d++;
    }
    //printf("%lld\n",d);
    return d;
}

int main()
{
    //n=20;
    //init();
    //demo();

    //return 0;
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        op.clear();
        scanf("%lld",&n);
        char str[10010];
        cin.getline(str,10010);
        cin.getline(str,10010);
        string s=str;
        stringstream ss(s);
        while(ss>>s)
            op.push_back(id(s));
        ll ans=1;
        for(ll i=1;i<=n;i++)
            for(ll j=1;j<=n;j++)
                if(!vis[i][j])
                    ans=lcm(ans,get(i,j));
        printf("%lld\n",ans);
        if(T) puts("");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
页面置换算法是操作系统中用于管理内存的一种算法。它的主要目的是在有限的物理内存中,尽可能多地运行进程。页面置换算法通过将内存中不常用的页面移出物理内存,以便为新的页面腾出空间。下面是一个页面置换算法模拟实验的例子: ```python # 定义一个函数,模拟页面置换算法 def page_replacement_algorithm(pages, capacity): # 初始化一个空的物理内存列表 memory = [] # 初始化一个计数器,用于记录页面置换次数 page_faults = 0 # 遍历所有页面 for page in pages: # 如果页面已经在物理内存中,跳过本次循环 if page in memory: continue # 如果物理内存未满,将页面添加到物理内存中 if len(memory) < capacity: memory.append(page) # 如果物理内存已满,使用页面置换算法将页面替换出去 else: # 初始化一个空的字典,用于记录每个页面最后一次出现的位置 last_occurrence = {} # 遍历物理内存中的所有页面,记录它们最后一次出现的位置 for i, p in enumerate(memory): if p not in last_occurrence: last_occurrence[p] = i # 找到最久未使用的页面,将其替换出去 page_to_replace = min(last_occurrence, key=last_occurrence.get) memory[memory.index(page_to_replace)] = page # 增加页面置换次数 page_faults += 1 # 返回页面置换次数 return page_faults # 测试页面置换算法模拟实验 pages = [7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2] capacity = 4 page_faults = page_replacement_algorithm(pages, capacity) print("页面置换次数:", page_faults) ``` 上述代码中,我们定义了一个名为`page_replacement_algorithm`的函数,它接受两个参数:`pages`表示所有页面的列表,`capacity`表示物理内存的容量。函数的返回值是页面置换的次数。在函数内部,我们首先初始化一个空的物理内存列表`memory`和一个计数器`page_faults`,然后遍历所有页面。如果页面已经在物理内存中,我们就跳过本次循环;如果物理内存未满,我们就将页面添加到物理内存中;如果物理内存已满,我们就使用页面置换算法将页面替换出去。在本例中,我们使用了最久未使用算法(LRU)来进行页面置换。最后,我们返回页面置换的次数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值