Codeforces Gym 101473D Folding Machine DFS/XJBS

http://codeforces.com/gym/101473/attachments


Problem D

Folding Machine

File: machine.[c|cpp|java]


One of the main tools of a Turing machine, which allows its computing power to be bigger than
other simpler models, is an infinite tape, divided in cells, where information is stored.
A Folding machine is a machine inspired by a Turing machine. In a Folding machine, the tape
is finite, the data are integers and instead of having the functionality of the original Turing machine,

this machine uses folding tape operations.


To perform a folding operation, the machine chooses a position between adjacent cells and folds
the tape, adding the values of overlapping cells, as can seen in the figure below.
5
dobra
6 23 8 19 7 10 5 6 23 8 5 16 30 27
6+10
23+7
19+8
Notice that the machine can also fold the tape before the tape center, as shown in the next figure.
The machine can also choose to fold at the tape start or at the tape end, actually inverting the tape.
1
dobra
2 3 4 5 6 7 1 2 7 6 5 5 5
1+4
2+3
7 6 5 4 3
Science of Bends Company is developing commercial versions of their Folding machine and its
production have recently raised. The last lot produced, unfortunately, have some issues and some
machines aren’t working properly. Some additional testing is therefore needed, to avoid selling defective

machines, which would denigrate the company’s image.


To test these machines, a set of tests and tapes are given. For each tape, the machine returns some
computation result. Therefore, the engineers responsible for testing take note of the results and can
verify if they are correct. But these engineers forgot to take note of which computation was made in

each test case.


To avoid re-testing all machines again, the engineers agreed that any combination of foldings is
sound and accepted if, from a given input, it generates the expected output. You were hired to develop
a program which, given the input and output tapes, determines whether there is a folding sequence

that, starting from the input tape, generates the output tape.


把一个数字序列反复折叠,折叠后重叠的位置的数字变为所有重复的数字和。问能否把所给序列折成所给的样子。


暴力dfs。

模拟过程挺复杂,调一调还是可以写出来的。


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=25,inf=0x3f3f3f3f;  
const ll llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);
int a[maxn],b[maxn];
int p[maxn][maxn];
int m,n;

bool check(int step) {
	for (int i=0;i<m;i++) {
		if (p[step][i]!=b[i]) return false;
	}
	return true;
}

bool inverse(int step) {
	for (int i=0;i<m;i++) {
		if (p[step][m-i-1]!=b[i]) return false;
	}
	return true;
}

bool dfs(int len,int step) {
	if (len<m) return false; 
	if (len==m) 
	    if (check(step-1)||inverse(step-1)) return true; else return false;
	bool z=false;
	int i;
	for (i=1;i<=len/2;i++) {
		int lc=i-1,rc=i;
		while (lc>=0&&rc<len) {
			p[step][lc]=p[step-1][lc]+p[step-1][rc];
			lc--;rc++;
		}
		for (int j=rc;j<len;j++) p[step][j-i]=p[step-1][j];
	//	for (int j=0;j<len-i;j++) printf("%d ",p[step][j]);
     //	printf("\n");
		z=z|dfs(len-i,step+1);
	}
	for (i=len/2+1;i<len;i++) {
		int lc=i-1,rc=i;
		while (lc>=0&&rc<len) {
			p[step][lc]=p[step-1][lc]+p[step-1][rc];
			lc--;rc++;
		}
		for (int j=0;j<=lc;j++) p[step][j]=p[step-1][j];
	//	for (int j=0;j<i;j++) printf("%d ",p[step][j]);
    // 	printf("\n");
		z=z|dfs(i,step+1);
	}
	return z;
}

int main() {
//	freopen("F.in","r",stdin);
//	freopen("F.out","w",stdout);
	scanf("%d",&n);
	int i;
	for (i=0;i<n;i++) {
		scanf("%d",&a[i]); 
		p[0][i]=a[i];
	}
	scanf("%d",&m);
	for (i=0;i<m;i++) {
		scanf("%d",&b[i]); 
	}
	if (dfs(n,1)) printf("S"); else printf("N");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值