POJ1288 Sly Number(高斯消元 dfs枚举)

由于解集只为{0, 1, 2}故消元后需dfs枚举求解

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 60, INF = 0x3F3F3F3F;

int a[N][N], mod;
int x[N];
int n, row;
int ans[N];
bool ok;

int gauss(int a[][N], int n){
	int i, j;
	for(i = 0, j = 0; i < n && j < n; i++, j++){
		int r = i;
		for(int k = i; k < n; k++){
			if(a[k][j]){
				r = k;
				break;
			}
		}
		if(a[r][j] == 0){
			i--;
			continue;
		}
		if(r != i){
			for(int k = 0; k <= n; k++){
				swap(a[i][k], a[r][k]);
			}
		}
		for(int k = i + 1; k < n; k++){
			if(a[k][j]){
				int x1 = a[i][j], x2 = a[k][j];
				for(int l = j; l <= n; l++){
					a[k][l] = (a[k][l] * x1 - x2 * a[i][l]) % mod;
				}
			}
		}
	}
	return i;
}

void dfs(int r){
	if(r == -1){
		ok = 1;
		return;
	}
	if(ok){
		return;
	}
	int x = 0;
	while(x < n && a[r][x] == 0){
		x++;
	}
	if(x == n){
		if(a[r][n]){
			return;
		}
		for(ans[x] = 0; ans[x] <= 2; ans[x]++){
			dfs(r - 1);
		}
		return;
	}
    int tp = 0;
	for(int j = x + 1; j < n; j++){
		tp += a[r][j] * ans[j];
		tp %= mod;
	}
	for(ans[x] = 0; ans[x] <= 2; ans[x]++){
		if((ans[x] * a[r][x] + tp - a[r][n]) % mod == 0){
			dfs(r - 1);
		}
	}
}

int main(){
    int t;
    cin>>t;
    while(t--){
    	cin >> mod >> n;
    	for(int i = 0; i < n; i++){
    		cin >> x[i];
    	}
    	for(int i = 0; i < n; i++){
    		a[i][n] = (i == 0);
    		for(int j = 0, k = i; j <= i; j++ , k--){
    			a[i][j] = x[k];
    		}
    		for(int j = i + 1, k = n -1; j < n; j++, k--){
    			a[i][j] = x[k];
    		}
    	}
    	row = gauss(a, n);
    	ok = 0;
    	dfs(n - 1);
    	if(ok){
    		printf("A solution can be found\n");
    	}else{
    		printf("No solution\n");
    	}

    }

    return 0;
}

  

时间: 2024-07-29 00:36:03

POJ1288 Sly Number(高斯消元 dfs枚举)的相关文章

POJ 1681 Painter&#39;s Problem 【高斯消元 二进制枚举】

任意门:http://poj.org/problem?id=1681 Painter's Problem Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7667   Accepted: 3624 Description There is a square wall which is made of n*n small square bricks. Some bricks are white while some bric

bzoj3811 玛里苟斯 高斯消元&amp;dfs

这道题目还要根据k来分类讨论.... 当k=1的时候,按位求贡献,然后发现答案就是所有数or起来再/2. 当k=2的时候,就真的要按位来了..按照(x1+x2+...+xn)^2展开x1x1+x1x2+x1x3...+xnxn,枚举i,j表示后面式子的下标.然后一个数就变成(0/1,0/1)二元组,当选出的数二元组异或后为(1,1)的时候有2^(i+j)的贡献.显然根据k=1发现(1,1)概率应该是1/4,但特殊情况就是所有二元组都是(0,0)或者(1,1)的形式则概率为1/2. 当k>2的时候

[POJ1753]Flip Game(异或方程组,高斯消元,枚举自由变量)

题目链接:http://poj.org/problem?id=1753 题意:同上. 这回翻来翻去要考虑自由变元了,假设返回了自由变元数量,则需要枚举自由变元. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 10 ┛┗┛┗┛┃ 11 ┓┏┓┏┓┃ 12 ┛┗┛┗┛┃ 13 ┓┏┓┏┓┃ 14 ┃┃┃┃┃┃ 15 ┻┻┻┻┻┻ 16 *

[HIHO1196]高斯消元&#183;二(高斯消元、枚举自由变元)

题目链接:http://hihocoder.com/problemset/problem/1196 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef pair<int, int> pii; 5 const int maxn = 230; 6 int equ, var; 7 int a[maxn][maxn]; 8 int x[maxn]; 9 int free_x[maxn]; 10 int free_num

POJ 1681 Painter&#39;s Problem (高斯消元)

题目地址:POJ 1681 跟前两题几乎一模一样的...不多说了.高斯消元+自由元枚举. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include &

BZOJ2115 WC2011 Xor DFS+高斯消元

题意:给定一张无向图,求1到N异或和最大的路径,允许重复经过. 题解:首先跑出1到N的一条路径,答案就是在这条路径上不断加环.首先用DFS处理出所有基环的异或和(其他环一定由基环构成,重复部分异或之后就会消掉),然后就是从一堆数里选任意个数使得异或和最小了,怎么做可以去看莫涛的课件(同解01异或方程),这里我简单介绍一下. 通过高斯消元,我们对原来的数进行操作,使得所有原来的数都可以用操作之后的数来组合而成(这玩意貌似叫线性基啊).具体做法就是从高到低暴力枚举每一位i,找到一个第i位为1的数j,

poj1753--Flip Game(高斯消元问题2,枚举自由元的首杀)

Flip Game Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white an

uva 1560 - Extended Lights Out(枚举 | 高斯消元)

题目链接:uva 1560 - Extended Lights Out 题目大意:给定一个5?6的矩阵,每个位置上有一个灯和开关,初始矩阵表示灯的亮暗情况,如果按了这个位置的开关,将会导致周围包括自己位置的灯状态变换,求一个按开关位置,保证所有灯都灭掉. 解题思路: 枚举,枚举第一行的状态,然后递推出后面四行的状态. 高斯消元,对于每个位置对定变量,这样列出30个方程求解. C++ 枚举 #include <cstdio> #include <cstring> #include &

BZOJ 2115 Wc2011 Xor DFS+高斯消元

题目大意:给定一个无向图,每条边上有边权,求一条1到n的路径,使路径上权值异或和最大 首先一条路径的异或和可以化为一条1到n的简单路径和一些简单环的异或和 我们首先DFS求出任意一条1到n的简单路径以及图中所有最简单的简单环(环上不存在两个点可以通过环外边直连) 然后在一些数中选出一个子集,使它们与一个给定的数的异或和最大,这就是高斯消元的问题了 利用高斯消元使每一位只存在于最多一个数上 然后贪心求解即可 #include<cstdio> #include<cstring> #in