N元一次不定方程求整数解
N元一次不定方程求整数解test =
198a+180b+175c=11550
512a+345b+124c+56d=23456
1999a+1299b+1499c+2799d+2499e+3299f=2328450
a, b, c ...>= 0 整数解
运行示例
func 198a+180b+175c=11550
输出
0 0 66
0 35 30
5 12 48
5 47 12
10 24 30
15 1 48
15 36 12
20 13 30
25 25 12
30 2 30
35 14 12
45 3 12
count = 12
回复 1# dorodaloo
$ awk -f get_sol.awk get_sol.txt
753 50
----------
01 15
04 10
075
0 100
12 11
156
181
20 12
237
262
318
343
424
505
530
611
Call count=25
Anscount=16
198 180 175 11550
-----------------
0 066
03530
51248
54712
102430
15 148
153612
201330
252512
30 230
351412
45 312
Call count=25
Anscount=12
$ cat get_sol.txt
# a1*x1 + a2*x2 + a3*x3 + ...= sum
#a1 > a2 > a3 ... > 0, sum > a1
7 5 3 50
198 180 175 11550
# 512 345 124 56 23456
# 3299 2799 2499 1999 1499 1299 2328450
$ cat get_sol.awk
func xd(p,q){ return (q?xd(q,(p%q)):p) }
func ck(p,q) { return (!(p%q)) }
func err(s) {
print "\n*** ERR *** "s;
exit;
}
func get_a() {
delete a;
at = NF-1;
for(n=1; n<=at; n+=1) {
a = $n
n1 = n+1;
if ($n<$n1&&n!=at) err($n"<"$n1);
}
}
func get_b() {
delete b;
b = a;
for(n=1; n<at; n+=1) {
b = xd(a, b)
}
if (b != xd(m,b)){
print "***NO Solution***";
next;
}
}
func dm(m) {
for (n=0; n<at; n+=1) {
w = length(a);
sLen = length(int(m/a));
if(w < sLen ) {
w = sLen;
}
}
s = "";
for(n=at-1; n>=0; n-=1) {
s = sprintf("%s%*d ",s,w, a);
}
x=s m;
gsub(".","-",x);
print s m
print x;
}
func init(m) {
get_a();
dm(m);
get_b();
}
func get_ans( n) {
s = "";
for(n=at-1; n>=0; n-=1) {
s = sprintf("%s%*d ", s, w, v);
}
print s;
ans_cnt += 1;
}
func sol(a,t,m, cyc,n){
sol_cnt += 1;
t -= 1;
#print "t="t",a["t"]="a",m="m;
if(t == 0){
if(m%a==0){
v = int(m/a);
get_ans();
}
return;
}
cyc = int(m/a+1);
for (n=0; n<cyc; n+=1) {
nm = m - n * a;
if(ck(nm,b)){
v = n;
cnt += sol(a, t, nm);
}
}
}
{
if (/^#/) next;
sol_cnt=0;
ans_cnt=0;
m = $NF;
init(m);
sol(a,at,m);
print "Call count="sol_cnt;
print "Anscount="ans_cnt;
print "";
}
回复 2# jason680
Call count=25
Anscount=16
Call count=25
Anscount=12
赞一个{:qq11:}
看得云里雾里
一头雾水,大神, :mrgreen:
有没有C版本的
回复 3# dorodaloo
get_coin_cyc.c 改来的
http://bbs.chinaunix.net/forum.php?mod=redirect&goto=findpost&ptid=4291348&pid=24679072&fromuid=24785593
回复 4# jason680
仔细再看
竟然是同一道题 :mrgreen:
大神,求C代码 :mrgreen:
求get_coin_cyc2代码 :mrgreen: 回复 4# jason680
仔细再看看
if (CHECK(nm, b)){
v = n;
cnt += sol(a, t, nm);
}
赞一个{:qq11:}
回复 4# jason680
赞一个{:qq11:}
get_sol.awk
512 345 1245625 23456
-------------------------
0 0 0 1 936
0 0 026 880
0 0 051 824
...
44 0 2 516
44 0 3 120
45 0 2 3 0
COUNT = 449699
CALL= 555841
get_sol2.c
SUM = 23456
COE = 25 56 124 345 512
0 3 2 0 45
20 1 3 0 44
16 5 2 0 44
...
824 51 0 0 0
880 26 0 0 0
936 1 0 0 0
COUNT = 449699
CALL= 25536
帮我解决这个问题,非常感谢
回复 2# jason680
大神
不知如何释放
怎写destroy函数
void destroy(Node *no) {
/* HOW TO DESTROY? */
}
代码
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
unsigned ans;
struct Node *branch;
struct Node *node;
} Node;
typedef struct {
unsigned sum;
Node *node;
} Table;
Table *TAB;
unsigned SUM;
unsigned CALL;
unsigned gcd(unsigned, unsigned);
void calculate(unsigned *, unsigned, unsigned);
Table calUtil(unsigned *, unsigned, unsigned, unsigned *);
void print(Node *, unsigned, unsigned *, unsigned);
void destroy(Node *);
int main() {
//unsigned coefficient[] = { 25, 56, 124, 345, 512 };
//unsigned sum = 23456;
// 5a+10b+25c+50d=200 5 < 10 < 25 < 50
unsigned coefficient[] = {5, 10, 25, 50};
unsigned sum = 200;
unsigned num = sizeof(coefficient) / sizeof(unsigned);
calculate(coefficient, num, sum);
}
unsigned gcd(unsigned m, unsigned n) { return n ? gcd(n, m % n) : m; }
void destroy(Node *no) {
/* HOW TO DESTROY? */
}
void calculate(unsigned *coefficient, unsigned num, unsigned sum) {
CALL = 0;
SUM = sum;
unsigned Gcd;
Gcd = coefficient;
for (unsigned i = 1; i < num - 1; i++)
Gcd = gcd(coefficient, Gcd);
TAB = calloc(num * (SUM + 1), sizeof(Table));
Table ret = calUtil(coefficient, num - 1, sum, Gcd);
unsigned answer;
printf("SUM = %u\nCOE = ", sum);
for (int i = 0; i < num; i++) {
printf("%d ", coefficient);
}
printf("\n");
print(ret.node, num - 1, answer, num);
printf("COUNT = %u\n", ret.sum);
printf("CALL= %u\n", CALL);
// HOW TO DESTROY??
//destroy (ret.node);
//free (TAB);
}
void print(
Node *no,
unsigned index,
unsigned *ans,
unsigned num) {
if (!no) {
for (unsigned i = 0; i < num; i++)
printf("%u ", ans);
printf("\n");
}
while (no) {
ans = no->ans;
print(no->branch, index - 1, ans, num);
no = no->node;
}
}
Table calUtil(
unsigned *coefficient,
unsigned index,
unsigned sum,
unsigned *Gcd) {
CALL++;
Table(*tab) = (Table(*)) TAB;
if (!index) {
Node *n = calloc(1, sizeof(Node));
n->ans = sum / coefficient;
return tab = (Table){1, n};
}
Table this = {0};
unsigned newSum = sum;
unsigned max = sum / coefficient;
for (unsigned value = 0; value <= max; value++) {
/* HAS SOLUTION */
if (newSum % Gcd == 0) {
Table branch = tab.node
? tab
: calUtil(coefficient, index - 1, newSum, Gcd);
if (branch.sum) {
this.sum += branch.sum;
Node *node = malloc(sizeof(Node));
*node = (Node){value, branch.node, this.node};
this.node = node;
}
}
newSum -= coefficient;
}
return tab = this;
}
本帖最后由 dorodaloo 于 2018-02-11 21:09 编辑
审核中...:time::time:
大神 how to write destroy function
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
unsigned ans;
struct Node *branch;
struct Node *node;
} Node;
typedef struct {
unsigned sum;
Node *node;
} Table;
Table *TAB;
unsigned SUM;
unsigned CALL;
unsigned gcd(unsigned, unsigned);
void calculate(unsigned *, unsigned, unsigned);
Table calUtil(unsigned *, unsigned, unsigned, unsigned *);
void print(Node *, unsigned, unsigned *, unsigned);
void destroy(Node *);
int main() {
//unsigned coefficient[] = { 25, 56, 124, 345, 512 };
//unsigned sum = 23456;
// 5a+10b+25c+50d=200 5 < 10 < 25 < 50
unsigned coefficient[] = {5, 10, 25, 50};
unsigned sum = 200;
unsigned num = sizeof(coefficient) / sizeof(unsigned);
calculate(coefficient, num, sum);
}
unsigned gcd(unsigned m, unsigned n) { return n ? gcd(n, m % n) : m; }
void destroy(Node *no) {
/* HOW TO DESTROY? */
}
void calculate(unsigned *coefficient, unsigned num, unsigned sum) {
CALL = 0;
SUM = sum;
unsigned Gcd;
Gcd = coefficient;
for (unsigned i = 1; i < num - 1; i++)
Gcd = gcd(coefficient, Gcd);
TAB = calloc(num * (SUM + 1), sizeof(Table));
Table ret = calUtil(coefficient, num - 1, sum, Gcd);
unsigned answer;
printf("SUM = %u\nCOE = ", sum);
for (int i = 0; i < num; i++) {
printf("%d ", coefficient);
}
printf("\n");
print(ret.node, num - 1, answer, num);
printf("COUNT = %u\n", ret.sum);
printf("CALL= %u\n", CALL);
// HOW TO DESTROY??
//destroy (ret.node);
//free (TAB);
}
void print(
Node *no,
unsigned index,
unsigned *ans,
unsigned num) {
if (!no) {
for (unsigned i = 0; i < num; i++)
printf("%u ", ans);
printf("\n");
}
while (no) {
ans = no->ans;
print(no->branch, index - 1, ans, num);
no = no->node;
}
}
Table calUtil(
unsigned *coefficient,
unsigned index,
unsigned sum,
unsigned *Gcd) {
CALL++;
Table(*tab) = (Table(*)) TAB;
if (!index) {
Node *n = calloc(1, sizeof(Node));
n->ans = sum / coefficient;
return tab = (Table){1, n};
}
Table this = {0};
unsigned newSum = sum;
unsigned max = sum / coefficient;
for (unsigned value = 0; value <= max; value++) {
/* HAS SOLUTION */
if (newSum % Gcd == 0) {
Table branch = tab.node
? tab
: calUtil(coefficient, index - 1, newSum, Gcd);
if (branch.sum) {
this.sum += branch.sum;
Node *node = malloc(sizeof(Node));
*node = (Node){value, branch.node, this.node};
this.node = node;
}
}
newSum -= coefficient;
}
return tab = this;
}
尼玛, 发一帖究竟要审核多久:time:
页:
[1]
2