HDU 4119Isabella's Message2011成都现场赛I题(字符串模拟)

本文介绍了一个关于解密秘密信的问题,通过旋转带有洞口的遮罩来逐步揭示隐藏的信息,并利用已知词汇判断其含义,最终找到字典序最小且可理解的消息。

Isabella's Message

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1377    Accepted Submission(s): 406


Problem Description
Isabella and Steve are very good friends, and they often write letters to each other. They exchange funny experiences, talk about people around, share their feelings and write about almost everything through the letters. When the letters are delivered, they are quite afraid that some other people(maybe their parents) would peek. So they encrypted the letter, and only they know how to decrypt it. This guarantees their privacy.
The encrypted message is an N * N matrix, and each grid contains a character.
Steve uses a special mask to work as a key. The mask is N * N(where N is an even number) matrix with N*N/4 holes of size 1 * 1 on it.
The decrypt process consist of the following steps:
1. Put the mask on the encrypted message matrix
2. Write down the characters you can see through the holes, from top to down, then from left to right.
3. Rotate the mask by 90 degrees clockwise.
4. Go to step 2, unless you have wrote down all the N*N characters in the message matrix.
5. Erase all the redundant white spaces in the message.
For example, you got a message shown in figure 1, and you have a mask looks like figure 2. The decryption process is shown in figure 3, and finally you may get a message "good morning".

You can assume that the mask is always carefully chosen that each character in the encrypted message will appear exactly once during decryption.
However, in the first step of decryption, there are several ways to put the mask on the message matrix, because the mask can be rotated (but not flipped). So you may get different results such as "od morning go" (as showed in figure 4), and you may also get other messages like "orning good m", "ng good morni".

Steve didn't know which direction of the mask should be chosen at the beginning, but after he tried all possibilities, he found that the message "good morning" is the only one he wanted because he couldn't recognize some words in the other messages. So he will always consider the message he can understand the correct one. Whether he can understand a message depends whether he knows all the words in the message. If there are more than one ways to decrypt the message into an understandable one, he will choose the lexicographically smallest one. The way to compare two messages is to compare the words of two messages one by one, and the first pair of different words in the two messages will determine the lexicographic order of them.
Isabella sends letters to Steve almost every day. As decrypting Isabella's message takes a lot of time, and Steve can wait no longer to know the content of the message, he asked you for help. Now you are given the message he received, the mask, and the list of words he already knew, can you write a program to help him decrypt it?
 

Input
The first line contains an integer T(1 <= T <= 100), indicating the number of test cases.
Each test case contains several lines.
The first line contains an even integer N(2 <= N <= 50), indicating the size of the matrix.
The following N lines each contains exactly N characters, reresenting the message matrix. The message only contains lowercase letters and periods('.'), where periods represent the white spaces.
You can assume the matrix contains at least one letter.
The followingN lines each containsN characters, representing the mask matrix. The asterisk('*') represents a hole, and period('.') otherwise. The next line contains an integer M(1 <= M <= 100), the number of words he knew.
Then the following M lines each contains a string represents a word. The words only contain lowercase letters, and its length will not exceed 20.
 

Output
For each test case in the input, print one line: "Case #X: Y", where X is the test case number (starting with 1) and Y is Isabella's message.
If Steve cannot understand the message, just print the Y as "FAIL TO DECRYPT".
 

Sample Input
  
3 4 o.do .ng. grmn o.i. .*.. *.*. .... *... 2 good morning 4 ..lf eoyv oeou vrer ..*. .*.. .... *.*. 5 i you the love forever 4 .sle s.c. e.fs ..uu *... .*.. ...* ..*. 1 successful
 

Sample Output
  
Case #1: good morning Case #2: love you forever Case #3: FAIL TO DECRYPT
 

Source
 



题目大意:给一个n*n的矩阵,n为偶数,矩阵由小写字母和'.'组成,'.'表示空格,再给一个n*n矩阵,由'.'和'*'组成,'*'表示洞,'.'表示障碍。

现在将2张卡片重合,将能看到的字符从上往下从左往右依次取出组成一个新单词。卡片可以顺时针旋转90度,再取出能看到的

单词,一共有4个单词,4个单词再依次组成一个句子,因为卡片是连续转动的,所以4个单词首尾相连,任取一个做句子头,所

以句子一共也是4个。再给m个单词,求出字典序最小的句子并要求句子中每个单词都在给定的m个单词中。

坐标转换公式(i,j)——> (j,n-i+1) 坐标变换公式,从1,1开始。

先求出4个字符串连接好形成的字符串,然后改变连接顺序,组成新的4个字符串连接好形成的字符串。然后查找是否全部由单词本中的单词组成。(这段话来自于Hadis_yuki)


        解题思路:开始是中间的连续的空格没有处理好,然后还有map没有初始化,结果WA出翔了。终于A了,当时比赛如果我做的话,可能会一WA到底。。需要修炼啊!


        题目地址:Isabella's Message


AC代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<cstdio>
#include<algorithm>
using namespace std;
char a[55][55];     //开始的地图
char tmp[55][55];
char mes[10005];  //存放连接好以后的字符串,还没有去空格
string res[5];
int visi[55][55]; //表示洞
int vis[55][55];  //visi的temp
int n,w;
map <string,int> word;  //认识的单词

int cmp(string a,string b)
{
    if(a<b) return 1;
    return 0;
}

void rotat()  //顺时针旋转90度
{
    int i,j;
    memset(vis,0,sizeof(vis));
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
          if(visi[i][j]==1)
            vis[j][n+1-i]=1;
    memset(visi,0,sizeof(visi));
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
           visi[i][j]=vis[i][j];
}

void solve()
{

    int t=0; //如果存在一个满足条件则变为1
    int i,j,k,l;
    for(i=0;i<=3;i++)
        res[i]="";  //每次都要清空
    for(l=0;l<4;l++)
    {
        int flag=0;
        k=4;
        int p=0;
        while(k--)
        {
           for(i=1;i<=n;i++)
              for(j=1;j<=n;j++)
                if(visi[i][j]==1)
                   mes[p++]=a[i][j];
           rotat();
        }
        mes[p]='\0';  //mes是存放连接好以后的字符串,还没有去空格
        //cout<<mes<<endl;
        i=0;
        while(i<p)  //去前面的空格
        {
            if(mes[i]==' ')
                i++;
            else
                break;
        }

        j=p-1;  //去后面的空格
        while(j>=0)
        {
            if(mes[j]==' ')
                j--;
            else
                break;
        }
        p=j;
        //cout<<i<<" "<<p<<endl;
        //cout<<mes<<endl;
        char tmp1[55];
        int tt=0;
        for(j=i;j<=p;j++)
        {
            if(mes[j]==' '&&mes[j+1]==' ')  //处理中间的空格
                continue;
            else if(mes[j]==' '||j==p)
            {
                if(j==p)
                    tmp1[tt++]=mes[j];
                tmp1[tt]='\0';
                //cout<<tt<<endl;
                tt=0;
                //cout<<tmp1<<endl;
                if(word[tmp1])
                {
                    if(res[t]=="")
                        res[t]=res[t]+tmp1;
                    else
                        res[t]=res[t]+" "+tmp1;
                }
                else
                {
                    res[t]="";
                    flag=1;
                    break;
                }
            }
            else
            {
                tmp1[tt++]=mes[j];
            }
        }

        if(!flag) t++;
        rotat();
    }

    if(t==0)
        puts("FAIL TO DECRYPT");
    else
    {
        sort(res,res+t,cmp);
        cout<<res[0]<<endl;
    }
}

int main()
{
    int tes,i,j;
    scanf("%d",&tes);
    for(int te=1;te<=tes;te++)
    {
        memset(visi,0,sizeof(visi));
        scanf("%d",&n);
        for(i=1;i<=n;i++)
          scanf("%s",a[i]+1);  //a代表地图
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
              if(a[i][j]=='.')
                 a[i][j]=' ';
        for(i=1;i<=n;i++)
        {
            scanf("%s",tmp[i]+1);
            for(j=1;j<=n;j++)
                if(tmp[i][j]=='*')
                   visi[i][j]=1;   //visi代表*
        }

        scanf("%d",&w); //认识的单词数
        string temp;
        word.clear();
        for(i=0;i<w;i++)
        {
           cin>>temp;
           word[temp]=2;
        }
        //temp="}";
        //word[temp]=2;
        printf("Case #%d: ",te);
        solve();
    }

    /*int i,w;
    scanf("%d",&w); //认识的单词数
    string temp;
    for(i=0;i<w;i++)
    {
        cin>>temp;
        word[temp]=2;
    }
    temp="}";
    word[temp]=2;

    char tm[20];
    while(cin>>tm)
    {
        if(word[tm])
            cout<<"yes"<<endl;
        else
            cout<<"no"<<endl;
    }*/

    return 0;
}

/*
3
4
o.do
.ng.
grmn
o.i.
.*..
*.*.
....
*...
4
goo
morning
od
go
4
..lf
eoyv
oeou
vrer
..*.
.*..
....
*.*.
5
i
you
the
love
forever
4
.sle
s.c.
e.fs
..uu
*...
.*..
...*
..*.
1
successful
*/



【EI复现】基于主从博弈的新型城镇配电系统产消者竞价策略【IEEE33节点】(Matlab代码实现)内容概要:本文介绍了基于主从博弈理论的新型城镇配电系统中产消者竞价策略的研究,结合IEEE33节点系统,利用Matlab进行仿真代码实现。该研究聚焦于电力市场环境下产消者(既生产又消费电能的主体)之间的博弈行为建模,通过构建主从博弈模型优化竞价策略,提升配电系统运行效率与经济性。文中详细阐述了模型构建思路、优化算法设计及Matlab代码实现过程,旨在复现高水平期刊(EI收录)研究成果,适用于电力系统优化、能源互联网及需求响应等领域。; 适合人群:具备电力系统基础知识和一定Matlab编程能力的研究生、科研人员及从事能源系统优化工作的工程技术人员;尤其适合致力于电力市场博弈、分布式能源调度等方向的研究者。; 使用场景及目标:① 掌握主从博弈在电力系统产消者竞价中的建模方法;② 学习Matlab在电力系统优化仿真中的实际应用技巧;③ 复现EI级别论文成果,支撑学术研究或项目开发;④ 深入理解配电系统中分布式能源参与市场交易的决策机制。; 阅读建议:建议读者结合IEEE33节点标准系统数据,逐步调试Matlab代码,理解博弈模型的变量设置、目标函数构建与求解流程;同时可扩展研究不同市场机制或引入不确定性因素以增强模型实用性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值