ACM PKU 1048 Follow My Logic
来源:互联网 发布:淘宝一分钱秒评 编辑:程序博客网 时间:2024/05/16 05:42
ACM PKU 1048 Follow My Logic
2009/04/02 0 Comments
Follow My Logic 题目重述
对于一个逻辑电路和给定的输入值,计算该电路的输出值。该逻辑电路有一个或多个输入端, 零个或多个逻辑门电路,和一个输出端。本题中用标准ASCll字符来表示逻辑电路:横竖导线分别用‘-’和‘|’表示,转折点用‘+’表示,输入端用大写字母‘A’-’Z’表示,输出端用问号‘?’表示,小写字母‘o’表示取反。与门、或门及电路各部分示例如下:
:/ :/ -:/ -o:/ A-o:/
: ) : > : )- : )o- : )o-?
:/ :/ -:/ --:/ B-- :/
与门 或门 带输入输出 输入输出 完整电路
的门电路 取反的门电路
输入:
输入数据包含多个输入数据块。每个输入数据块包含以下部分:
一个电路图,以上述形式表示,用只含‘*’的单独一行结束。
多行01字符串,每行对应一组数据,包含26个0或1,分别对应A-Z的值。用只含‘*’的单独一行结束
输出:
对每组输入数据,输出对应的电路输出值。
每个结果占一行。
不同输入数据块的输出结果之间用空行隔开。
这是一道模拟类的题目
第一种思路:
模拟人读逻辑电路的做法,按照逻辑电路的走向确定在门电路的各个输入端的值,计算门电路输出端的值。如此反复,最终求得电路的输出值。
第二种思路:
自上至下,自左至右,顺序求解。
关键:
确定电路在交叉点的走向;
从门电路的一段输入电路转到另一段电路。
根据算法要求需要存储的数据有
1.int row, column 用来表示电路图的行数和最大宽度;
2.int ish, dir 用来表示电路走向(水平或竖直、正向或负向);
2.char logic[100][100] 用来存储逻辑电路图;
3.int state[100][100] 用来存储电路上每一个点的值;
4.int value[26] 用来存储A-Z的值。
确定电路在交叉点的走向
根据题意,没有两个交叉点相邻,一个交叉点周围只有‘-’和‘|’。分两种情况讨论。
if(ish) //原先为水平方向
{
if(x dir=1;
else //转向上
dir=-1;
ish=0;
x+=dir;
}
else //原先为垂直方向
{
if(y dir=1; //转向右
else
dir=-1; //转向左
ish=1;
y+=dir;
}
电路分析流程:
通过两个函数hdsearch()和process()的嵌套调用实现。
process() 用于从某一位置根据电路走向计算下一位置的值,直至获得输出结果,或到达某一门电路无法继续。
hdsearch() 用于从某一位置寻找这段电路的开头(字母输入值)。
程序从process()开始,直至某一门电路因另一输入端没有计算而无法继续。调用hdsearch()寻找到另一输入端所在电路的开头,然后调用process()继续计算。如此递归调用,直至获得最终输出结果。
#include
#include
int state[100][100],value[26],row,column,done;
char logic[100][100];
void hdsearch(int x,int y)
{
int dir,ish;
void process(int x,int y);
if(done)return;
dir=-1;ish=1;
while(!done)
{
if(logic[x][y]>='A'&&logic[x][y]<='Z')
process(x,y);
else switch(logic[x][y])
{
case '-':
case 'o':
case ':':
case '//':
case '/':
y=y+dir;
break;
case '|':
x+=dir;
break;
case ')':
case '>':
if(state[x-1][y-1]==-1)
{x--;y--;}
else if(state[x+1][y-1]==-1)
{x++;y--;}
else
{
if(logic[x][y]==')')
state[x][y]=state[x-1][y]&state[x+1][y];
else
state[x][y]=state[x-1][y]|state[x+1][y];
process(x,y);
}
break;
case '+':
if(ish)
{
if(x dir=1;
else
dir=-1;
ish=0;
x+=dir;
}
else
{
if(y dir=1;
else
dir=-1;
ish=1;
y+=dir;
}
break;
}
}
return;
}
void process(int x,int y)
{
int dir,ish;
void hdsearch(int x,int y);
if(done)return;
if(logic[x][y]>='A'&&logic[x][y]<='Z')
{
state[x][y]=value[logic[x][y]-'A'];
if(y {
ish=1;
dir=1;
y++;
state[x][y]=state[x][y-1];
}
else if(y>0&&logic[x][y-1]=='-')
{
ish=1;
dir=-1;
y--;
state[x][y]=state[x][y+1];
}
else if(x {
ish=0;
dir=1;
x++;
state[x][y]=state[x-1][y];
}
else if(x>0&&logic[x-1][y]=='|')
{
ish=0;
dir=-1;
x--;
state[x][y]=state[x+1][y];
}
}
else
{
ish=1;
dir=1;
}
while(!done)
{
switch(logic[x][y])
{
case '-':
case ':':
case ')':
case '>':
y+=dir;
state[x][y]=state[x][y-dir];
break;
case 'o':
y+=dir;
state[x][y]=state[x][y-dir]^1;
break;
case '|':
x+=dir;
state[x][y]=state[x-dir][y];
break;
case '//':
if(state[x+2][y]==-1)
hdsearch(x+2,y);
else
{
x++;
y++;
if(logic[x][y]==')')
state[x][y]=state[x-1][y-1]&state[x+1][y-1];
else
state[x][y]=state[x-1][y-1]|state[x+1][y-1];
}
break;
case '/':
if(state[x-2][y]==-1)
hdsearch(x-2,y);
else
{
x--;
y++;
if(logic[x][y]==')')
state[x][y]=state[x-1][y-1]&state[x+1][y-1];
else
state[x][y]=state[x-1][y-1]|state[x+1][y-1];
}
break;
case '+':
if(ish)
{
if(x dir=1;
else
dir=-1;
ish=0;
x+=dir;
state[x][y]=state[x-dir][y];
}
else
{
if(y dir=1;
else
dir=-1;
ish=1;
y+=dir;
state[x][y]=state[x][y-dir];
}
break;
case '?':
printf("%d/n",state[x][y]);
done=1;
break;
}
}
return;
}
int main()
{
int i,j,flag;
char c;
while(scanf("%c",&c)==1)
{
column=0;
for(i=0;(i>0?(c=getchar()):1)&&c!='*';i++)
{
if(c=='/n'){i--;continue;}
logic[i][0]=c;
for(j=1;(c=getchar())!='/n';j++)
{
logic[i][j]=c;
}
if(j>column)
column=j;
for(;j<100;j++)
logic[i][j]=' ';
}
c=getchar();
while(c=='/n')c=getchar();
row=i;
while(c!='*')
{
if(c=='/n')continue;
value[0]=c-'0';
for(i=1;i<26;i++)
{
value[i]=getchar();
value[i]-='0';
}
c=getchar();
for(i=0;i for(j=0;j state[i][j]=-1;
flag=0;
for(j=0;j for(i=0;i if(logic[i][j]>='A'&&logic[i][j]<='Z')
{flag=1;break;}
done=0;
process(i,j-1);
c=getchar();
}
printf("/n");
c=getchar();
}
return 0;
}
所有递归调用都在计算出最终结果后才返回,可用简单循环代替。Hdsearch()可作为process()的一个分支的一部分。
总结:
模拟类的程序,可以完全模拟人的思维方式进行,也可以充分利用题目中的简化条件,制定适合计算机的搜索策略。
模拟类的程序,关键要分析处理过程,找出其中的难点进行重点突破。
对于一个逻辑电路和给定的输入值,计算该电路的输出值。该逻辑电路有一个或多个输入端, 零个或多个逻辑门电路,和一个输出端。本题中用标准ASCll字符来表示逻辑电路:横竖导线分别用‘-’和‘|’表示,转折点用‘+’表示,输入端用大写字母‘A’-’Z’表示,输出端用问号‘?’表示,小写字母‘o’表示取反。与门、或门及电路各部分示例如下:
:/ :/ -:/ -o:/ A-o:/
: ) : > : )- : )o- : )o-?
:/ :/ -:/ --:/ B-- :/
与门 或门 带输入输出 输入输出 完整电路
的门电路 取反的门电路
输入:
输入数据包含多个输入数据块。每个输入数据块包含以下部分:
一个电路图,以上述形式表示,用只含‘*’的单独一行结束。
多行01字符串,每行对应一组数据,包含26个0或1,分别对应A-Z的值。用只含‘*’的单独一行结束
输出:
对每组输入数据,输出对应的电路输出值。
每个结果占一行。
不同输入数据块的输出结果之间用空行隔开。
这是一道模拟类的题目
第一种思路:
模拟人读逻辑电路的做法,按照逻辑电路的走向确定在门电路的各个输入端的值,计算门电路输出端的值。如此反复,最终求得电路的输出值。
第二种思路:
自上至下,自左至右,顺序求解。
关键:
确定电路在交叉点的走向;
从门电路的一段输入电路转到另一段电路。
根据算法要求需要存储的数据有
1.int row, column 用来表示电路图的行数和最大宽度;
2.int ish, dir 用来表示电路走向(水平或竖直、正向或负向);
2.char logic[100][100] 用来存储逻辑电路图;
3.int state[100][100] 用来存储电路上每一个点的值;
4.int value[26] 用来存储A-Z的值。
确定电路在交叉点的走向
根据题意,没有两个交叉点相邻,一个交叉点周围只有‘-’和‘|’。分两种情况讨论。
if(ish) //原先为水平方向
{
if(x dir=1;
else //转向上
dir=-1;
ish=0;
x+=dir;
}
else //原先为垂直方向
{
if(y dir=1; //转向右
else
dir=-1; //转向左
ish=1;
y+=dir;
}
电路分析流程:
通过两个函数hdsearch()和process()的嵌套调用实现。
process() 用于从某一位置根据电路走向计算下一位置的值,直至获得输出结果,或到达某一门电路无法继续。
hdsearch() 用于从某一位置寻找这段电路的开头(字母输入值)。
程序从process()开始,直至某一门电路因另一输入端没有计算而无法继续。调用hdsearch()寻找到另一输入端所在电路的开头,然后调用process()继续计算。如此递归调用,直至获得最终输出结果。
#include
#include
int state[100][100],value[26],row,column,done;
char logic[100][100];
void hdsearch(int x,int y)
{
int dir,ish;
void process(int x,int y);
if(done)return;
dir=-1;ish=1;
while(!done)
{
if(logic[x][y]>='A'&&logic[x][y]<='Z')
process(x,y);
else switch(logic[x][y])
{
case '-':
case 'o':
case ':':
case '//':
case '/':
y=y+dir;
break;
case '|':
x+=dir;
break;
case ')':
case '>':
if(state[x-1][y-1]==-1)
{x--;y--;}
else if(state[x+1][y-1]==-1)
{x++;y--;}
else
{
if(logic[x][y]==')')
state[x][y]=state[x-1][y]&state[x+1][y];
else
state[x][y]=state[x-1][y]|state[x+1][y];
process(x,y);
}
break;
case '+':
if(ish)
{
if(x dir=1;
else
dir=-1;
ish=0;
x+=dir;
}
else
{
if(y dir=1;
else
dir=-1;
ish=1;
y+=dir;
}
break;
}
}
return;
}
void process(int x,int y)
{
int dir,ish;
void hdsearch(int x,int y);
if(done)return;
if(logic[x][y]>='A'&&logic[x][y]<='Z')
{
state[x][y]=value[logic[x][y]-'A'];
if(y {
ish=1;
dir=1;
y++;
state[x][y]=state[x][y-1];
}
else if(y>0&&logic[x][y-1]=='-')
{
ish=1;
dir=-1;
y--;
state[x][y]=state[x][y+1];
}
else if(x {
ish=0;
dir=1;
x++;
state[x][y]=state[x-1][y];
}
else if(x>0&&logic[x-1][y]=='|')
{
ish=0;
dir=-1;
x--;
state[x][y]=state[x+1][y];
}
}
else
{
ish=1;
dir=1;
}
while(!done)
{
switch(logic[x][y])
{
case '-':
case ':':
case ')':
case '>':
y+=dir;
state[x][y]=state[x][y-dir];
break;
case 'o':
y+=dir;
state[x][y]=state[x][y-dir]^1;
break;
case '|':
x+=dir;
state[x][y]=state[x-dir][y];
break;
case '//':
if(state[x+2][y]==-1)
hdsearch(x+2,y);
else
{
x++;
y++;
if(logic[x][y]==')')
state[x][y]=state[x-1][y-1]&state[x+1][y-1];
else
state[x][y]=state[x-1][y-1]|state[x+1][y-1];
}
break;
case '/':
if(state[x-2][y]==-1)
hdsearch(x-2,y);
else
{
x--;
y++;
if(logic[x][y]==')')
state[x][y]=state[x-1][y-1]&state[x+1][y-1];
else
state[x][y]=state[x-1][y-1]|state[x+1][y-1];
}
break;
case '+':
if(ish)
{
if(x dir=1;
else
dir=-1;
ish=0;
x+=dir;
state[x][y]=state[x-dir][y];
}
else
{
if(y dir=1;
else
dir=-1;
ish=1;
y+=dir;
state[x][y]=state[x][y-dir];
}
break;
case '?':
printf("%d/n",state[x][y]);
done=1;
break;
}
}
return;
}
int main()
{
int i,j,flag;
char c;
while(scanf("%c",&c)==1)
{
column=0;
for(i=0;(i>0?(c=getchar()):1)&&c!='*';i++)
{
if(c=='/n'){i--;continue;}
logic[i][0]=c;
for(j=1;(c=getchar())!='/n';j++)
{
logic[i][j]=c;
}
if(j>column)
column=j;
for(;j<100;j++)
logic[i][j]=' ';
}
c=getchar();
while(c=='/n')c=getchar();
row=i;
while(c!='*')
{
if(c=='/n')continue;
value[0]=c-'0';
for(i=1;i<26;i++)
{
value[i]=getchar();
value[i]-='0';
}
c=getchar();
for(i=0;i for(j=0;j state[i][j]=-1;
flag=0;
for(j=0;j for(i=0;i if(logic[i][j]>='A'&&logic[i][j]<='Z')
{flag=1;break;}
done=0;
process(i,j-1);
c=getchar();
}
printf("/n");
c=getchar();
}
return 0;
}
所有递归调用都在计算出最终结果后才返回,可用简单循环代替。Hdsearch()可作为process()的一个分支的一部分。
总结:
模拟类的程序,可以完全模拟人的思维方式进行,也可以充分利用题目中的简化条件,制定适合计算机的搜索策略。
模拟类的程序,关键要分析处理过程,找出其中的难点进行重点突破。
- ACM PKU 1048 Follow My Logic
- POJ 1048 Follow My Logic 已被翻译
- Follow My Logic(递归,模拟)
- zoj1071 Follow My Logic(没看题,不过据说很恶心,待ac)
- Follow My Dream
- follow my heart
- Follow My Heart
- Follow My Heart
- pku-acm
- ACM-PKU
- follow my heart ……
- I wanna follow my heart
- Follow My Heart----大二下
- follow my heart...Make a difference
- PKU ACM 题目分类
- acm pku 1088 滑雪
- PKU ACM 1579
- PKU ACM 1163
- 如何做好芯片验证之我见(1)
- 嵌入式系统软件的全过程质量保证
- 浅谈OFFSET、ADDR&LEA的区别
- 微软和开放,一段不得不说的往事
- Ubuntu下阅读chm文件
- ACM PKU 1048 Follow My Logic
- c#工厂模式与抽象工厂模式
- 关于FileOutputStream.writer(len,off,length)标准写法
- 操作系统支持
- Write a DIB to a JPEG File
- J2ME开发问题摘要一【N系列手机上使用FileSystemRegistry.listRoots()】
- 提高J2SE性能的代码技巧
- reactos操作系统实现(44)
- Java路径问题最终解决方案