[英]Counting and changing the 0s in a matrix that are surrounded by 1s - Python
[英]Program to fill a matrix with 1s and 0s to such that it satisfies the given row and column sums
我應該編寫一個程序,用 0 和 1 填充矩陣( flag[][]
,這里),以滿足給定的行和列總和。 行和列總和將通過添加a[][]
元素的小數部分來計算。 我寫了下面給出的代碼,當我只運行它的這部分時它可以工作:
#include<stdio.h>
#include<stdlib.h>
int main()
{int m=3;
int flag[3][3];
int rSum[] = {1,1,2};
int cSum[] = {2,1,1};
for(int i=0;i<m;i++)
{int k = 0;
for(int j=0;j<rSum[i];j++)
{
if(cSum[k] == 0)
{
j--;
k++;
}
else
{
flag[i][k] = 1;
cSum[k]--;
k++;
}
}
}
return 0;
}
但是整個代碼在運行時給出了錯誤的輸出。 整個代碼:
#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("Enter the size of matrix: ");
int m,n;
scanf("%d %d",&m,&n);
float a[m][n];
printf("Enter the elements: ");
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
scanf("%f",&a[i][j]);
}
}
float b[m][n];
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
b[i][j] = a[i][j] - (int)a[i][j];
printf("%f ",b[i][j]);
}
printf("\n");
}
printf("\n\n\n");
float rSum[m], cSum[n];
for(int i=0;i<n;i++)
{
cSum[i] = 0;
}
for(int i=0;i<m;i++)
{
rSum[i] = 0;
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
rSum[i] += b[i][j];
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cSum[i] += b[j][i];
}
}
printf("\nrSum:");
for(int i=0;i<m;i++)
{
printf("%f ",rSum[i]);
}
printf("\ncSum:");
for(int i=0;i<n;i++)
{
printf("%f ",cSum[i]);
}
int flag[m][n];
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
flag[i][j] = 0;
}
}
for(int i=0;i<m;i++)
{int k = 0;
for(int j=0;j<rSum[i];j++)
{
if(cSum[k] == 0)
{
j--;
k++;
}
else
{
flag[i][k] = 1;
cSum[k]--;
k++;
}
}
}
printf("\n\n\n");
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%d ",flag[i][j]);
}
printf("\n");
}
return 0;
}
任何人都可以指出我犯的錯誤嗎? 為什么第一個代碼可以正常工作,而第二個代碼不行? 另外,我對a[][]
輸入是{1.2 , 3.4, 2.4, 3.9, 4.0, 2.1, 7.9, 5.6, 0.5}
。
在您的程序中,您有一個在許多部分反復犯的大錯誤:不要將float
類型變量視為int
。
首先,您不應該將 ( ==
) float
與任何數字進行比較。 所以cSum[k] == 0
是錯誤的。 相反,您應該指定一個閾值並比較數字和閾值之間的距離。
所以改變這一行
if(cSum[k] == 0)
和
if (fabsf(cSum[k]) < epsilon) // You can set epsilon to 0.0005
其中epsilon
是一個非常小的數字(即float
型),可以用作閾值。
另外, cSum[k] -= 1.0f;
比cSum[k]--;
好得多cSum[k]--;
這不一定是錯誤的,但您應該告訴閱讀您的代碼的人cSum[k]
是一個float
。
最后,改變這一行
for(int j=0;j<rSum[i];j++)
和
for(int j=0;j<round(rSum[i]);j++)
我給你舉個例子。 認為
j = 2 rSum[i] = 2.00000000000000009
你對j < rSum[i]
什么j < rSum[i]
?
事實上,我們希望它們彼此相等,但由於浮點數的精度問題,它們並不相等。 檢查j < rSum[i]
得出的結論是rSum[i]
大於j
。 但這是錯誤的。 所以我們應該強迫他們平等。 因此,您可以使用round
函數來防止這種情況。 你會得到
j = 2 rSum[i] = 2.00000000000000000
簡而言之,在您的程序中,由於比較沒有成功,所以需要if
和for
部分。
僅更改此部分並添加( #include <math.h>
):
float epsilon = 0.0005f;
for(int i=0;i<m;i++)
{int k = 0;
for(int j=0;j<round(rSum[i]);j++)
{
if(fabsf(cSum[k]) <epsilon)
{
j--;
k++;
}
else
{
flag[i][k] = 1;
cSum[k] -= 1.0f;
k++;
}
}
}
之后,您將按預期找到輸出:
1 0 0
1 0 0
0 1 1
首先,我沒有看到您將矩陣設置為 0 的位置。如果您已經收到一個每個數字都為 0 的矩陣,請指定。
但我也認為您的邏輯通常無法解決給定的問題。 您正在使用一種貪婪的策略,該策略在當前可能的情況下放置一個數字。 但是您不能保證這對於最終解決方案是正確的。
假設您有以下矩陣:
1 0 0 - 1
0 0 1 - 1
1 0 1 - 2
| | |
2 0 2
如您所見,行的總和為 {1, 1, 2},列的總和為 {2, 0, 2}。 現在您的算法將正確地將 1 放在flag[0][0]
然后,當該行完成時,它將移動到下一行。
這里它將在第一列( flag[1][0]
)中放置一個 1,因為列總和仍然允許它,行總和也是如此。 現在我們再次移動到下一行,完成了第二行的總和。
第一列已經滿了,所以我們給它留 0。下一列只能有 0,因為它的總和是 0。所以我們只剩下第三列,我們在那里放了一個 1。但是現在我們的最終矩陣flag
如下所示:
1 0 0
1 0 0
0 0 1
這顯然是一個錯誤的答案。
我建議嘗試使用回溯來解決這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.