poj-1026

本文介绍了一种处理大规模位移模拟问题的有效算法。通过分析位移规律,利用位移循环特性,将大量位移操作简化为小规模的移动,有效避免了超时问题。文章还讨论了输入处理技巧及输出格式注意事项。
//188K  110MS   C++
#include <cstring>
#include <cstdio>
#include <iostream>

using namespace std;

char str1[205];
char str2[205];

int key[205];

int cycleLength[205];

// void replace(char * str, int keyLength, int strLength) {
//     memset(str2, 0, sizeof(str2));
//     for (int i = 0; i < keyLength; i++) {
//         int pos = key[i] - 1;
//         if (str[i] == 0 || str[i] == '\n') {
//             str2[pos] = ' ';
//         } else {
//             str2[pos] = str[i];
//         }
//     }
//     memcpy(str1, str2, sizeof(str1));
// }

// void solve(char * str, int keyLength, int repeatTime) {
//     // printf("%s\n", str);
//     int strLength = strlen(str);
//     for (int i = 1; i <= repeatTime; i++) {
//         replace(str, keyLength, strLength);
//     }
//     str[keyLength] = 0;
//     printf("%s\n", str);
// }

void getCycleLength(int * key, int keyLength) {
    for (int i = 1; i <= keyLength; i++) {
        int curCycleLength = 0;
        int nextPos = key[i-1];
        while(nextPos != i) {
            curCycleLength++;
            nextPos = key[nextPos-1];
        }
        // printf("%d %d\n", i, curCycleLength + 1);
        cycleLength[i-1] = curCycleLength + 1;
    }
}

// int move(int curPos) {
//     return key[curPos-1];
// }

int moveWithRepeatTime(int beginPos, int repeatTime) {
    if (repeatTime ==0) {
        return beginPos;
    }

    int curPos = beginPos;
    for (int i = 1; i <= repeatTime; i++) {
        curPos = key[curPos-1];
    }
    return curPos;
}

int main() {
    while(1) {
        int keyLength;
        memset(key, 0, sizeof(key));
        scanf("%d", &keyLength);

        if (keyLength == 0) {
            return 0;
        }

        for (int i = 0; i < keyLength; i++) {
            scanf("%d", &key[i]);
        }

        getCycleLength(key, keyLength);

        int repeatTime;
        while (1) {
            scanf("%d", &repeatTime);
            if (repeatTime == 0) {
                break;
            }
            char c;
            scanf("%c", &c);
            memset(str1, 0, sizeof(str1));
            // scanf("%9[^\n]", str1);
            
            for(int i = 0; i < keyLength; i++){
                str1[i] = ' ';
            }
            for(int i = 0; i < keyLength; i++){
                scanf("%c", &c);
                if(c == '\n'){
                    break;
                }
                str1[i] = c;
            }

            int length = strlen(str1);

            memset(str2, ' ', sizeof(str2));
            for (int i = 0; i < keyLength; i++) {
                int curRepeatTime = repeatTime%cycleLength[i];
                int newPos = moveWithRepeatTime(i+1, curRepeatTime);
                // printf("%d -> %d\n", i, newPos - 1);
                if (str1[i] == 0 || str1[i] == '\n') {
                    str2[newPos-1] = ' ';
                } else {
                    str2[newPos-1] = str1[i];
                }
            }
            str2[keyLength]= 0;
            printf("%s\n", str2);
        }
         printf("\n");
    }
}


原理上很简单,就是单纯的模拟,从一个位置移动到另一个位置,

但是题目会要求移动非常多的次数(上万),因此如果搞朴素的模拟,必然TLE。

因此,就要分析一下位移的规律了,对于长度为L的位移数组,最多经过L次,就可以移回原位,这样就算移动N次(N非常大),只需N%移动循环的次数就可以得到一个相对很小的移动次数,就不会TLE了。对每个位置都求解得到其位移循环的最大次数C,然后对每个位置模拟移动N%C次即可,

比如例子中的位移数组:

10
4 5 3 7 2 8 1 6 10 9

对于位置1的数: 1 ->4 -> 7 -> 1 循环最大次数是3

对于位置2的数:2->5->2 循环最大次数是2

对于位置3的数: 3->3, 1

............


该题还考空格输入, 用 scanf("%9[^\n]", str1);一直TLE,怀疑是某次输入被阻塞了,后来不得已一个一个字母的读取了。

最后还要注意,每个block要输出一个空行, 因为这个PE了几次....

计及风电并网运行的微电网及集群电动汽车综合需求侧响应的优化调度策略研究(Matlab代码实现)内容概要:本文研究了计及风电并网运行的微电网及集群电动汽车综合需求侧响应的优化调度策略,并提供了基于Matlab的代码实现。研究聚焦于在高渗透率可再生能源接入背景下,如何协调微电网内部分布式电源、储能系统与大规模电动汽车充电负荷之间的互动关系,通过引入需求侧响应机制,建立多目标优化调度模型,实现系统运行成本最小化、可再生能源消纳最大化以及电网负荷曲线的削峰填谷。文中详细阐述了风电出力不确定性处理、电动汽车集群充放电行为建模、电价型与激励型需求响应机制设计以及优化求解算法的应用。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事新能源、微电网、电动汽车等领域技术研发的工程师。; 使用场景及目标:①用于复现相关硕士论文研究成果,深入理解含高比例风电的微电网优化调度建模方法;②为开展电动汽车参与电网互动(V2G)、需求侧响应等课题提供仿真平台和技术参考;③适用于电力系统优化、能源互联网、综合能源系统等相关领域的教学与科研项目开发。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注模型构建逻辑与算法实现细节,同时可参考文档中提及的其他相关案例(如储能优化、负荷预测等),以拓宽研究视野并促进交叉创新。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值