简体   繁体   English

我的代码有什么问题[Dfs,动态编程]

[英]what's wrong with my code [ Dfs , Dynamic programming ]

i tried to solve this problem with dfs and dynamic programming.我试图用 dfs 和动态编程来解决这个问题。 then i submit my code to my school grader but the answer is wrong.然后我将我的代码提交给我的学校评分员,但答案是错误的。 am i implement something wrong with dfs.我是不是用 dfs 实现了一些错误。 what's wrong with my code.我的代码有什么问题。

PS.sorry for my bad english PS.对不起我的英语不好

The problem:问题:

given a random number there's 2 different way you can do with this number给定一个随机数,你可以用 2 种不同的方式处理这个数字
1.divide it by 3 (it has to be divisible) 1.除以3(它必须是整除的)
2.multiply it by 2 2.乘以2

given n number find the original order before it was swapped给定 n 个数字,在交换之前找到原始订单
----EXAMPLE1---- ----示例1----
INPUT: 6输入:6
4 8 6 3 12 9 4 8 6 3 12 9
OUTPUT: 9 3 6 12 4 8 OUTPUT:9 3 6 12 4 8
----EXAMPLE2---- ----示例2----
INPUT: 4输入:4
42 28 84 126 42 28 84 126
OUTPUT: 126 42 84 28 OUTPUT:126 42 84 28

Here's my code这是我的代码

#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
int n ;
int input[51];
map<int,int> order ;
map<int,int> memo ;

bool valid(int a){
    for(int i=0;i<n;i++){
        if(input[i]==a)return 1 ;
    }
    return 0 ;
}
void dfs(int st){
    memo[st]=1;
    if(valid(st/3)){
        if(memo[st/3]==0){
            dfs(st/3);
            order[st]+=order[st/3];
        }
        else order[st]+=order[st/3];
    }
    if(valid(st*2)){
        if(memo[st*2]==0){
            dfs(st*2);
            order[st]+=order[st*2];
        }
        else order[st]+=order[st*2];
    }
}

int main(){
    cin >>  n ;
    for(int i=0;i<n;i++){
        cin >> input[i];
        memo[input[i]]=0;
        order[input[i]]=1;
    }
    for(int i=0;i<n;i++){
        if(memo[input[i]]==0)dfs(input[i]);
    }

    for(int i=n;i>=1;i--){
        for(int k=0;k<n;k++){
            if(order[input[k]]==i){
                printf("%d ",input[k]);
                break;
            }
        }
    }
}

  • Information the OP should have told us in the first place : OP应该首先告诉我们的信息

my code gave the correct answer only 7 of 10 test case.i've already asked my teacher he only told me to be careful with the recursion.我的代码在 10 个测试用例中只给出了 7 个正确答案。我已经问过我的老师,他只告诉我要小心递归。 but i couldn't figure it out what's wrong with my recursion or something else但我无法弄清楚我的递归或其他什么问题

  • An example that "fails":一个“失败”的例子:

Here's a failing case: Say you have the sequence 3 1 2 4. valid will return true for 4 / 3 because it sees 1 in the sequence.这是一个失败的案例:假设您有序列 3 1 2 4。valid 将为 4 / 3 返回 true,因为它在序列中看到 1。 – Calculuswhiz – 微积分高手

  • the better solution更好的解决方案
#include<bits/stdc++.h>
using namespace std;
struct number{
    long long int r , f3 , f2 ;
};
vector<number> ans ;
bool cmp(number a,number b){
    if(a.f3!=b.f3)return a.f3>=b.f3;
    if(a.f2!=b.f2)return a.f2<=b.f2;
    return true ;
}
int main(){
    int n ;cin>> n ;
    long long int input ;
    
    for(int i=0;i<n;i++){
        cin >> input ;
        long long int r = input ;
        long long int f3 = 0, f2 = 0 ;
        while(input%3==0){
            f3++;
            input/=3;
        }
        while(input%2==0){
            f2++;
            input/=2;
        }
        ans.push_back({r,f3,f2});
    }
    sort(ans.begin(),ans.end(),cmp);

    for(auto i : ans){
        cout << i.r << " " ;
    }
}

The darkest place is under the lamp.最黑暗的地方在灯下。

Look at the problem definition:看问题定义:

1.divide it by 3 (it has to be divisible) 1.除以3(它必须是整除的)

Where do you test for the divisibility?你在哪里测试可分性?

So, one error is here:所以,这里有一个错误:

if(valid(st/3)){

This test should read:该测试应为:

if(st % 3 == 0 && valid(st/3)){

With this simple improvement, all three test cases pass.通过这个简单的改进,所有三个测试用例都通过了。

A hint to improve (simplify) the solution改进(简化)解决方案的提示

Numbers that are not divisible by 3 must come after those divisible.不能被 3 整除的数必须排在能被 3 整除的数之后。 Similarly, those not divisible by 9 must be coming after those that does.同样,那些不能被 9 整除的必须在那些能被 9 整除的之后。 Similarly for 27, 81,...同样对于 27、81、...

Now, if you divide your numbers into subsets of numbers of the form n = 3^k*m, where m % 3,= 0. then in each such a subset the only operation allowed by your algorithm is "multiply by 2".现在,如果您将您的数字划分为 n = 3^k*m 形式的数字子集,其中 m % 3,= 0。那么在每个这样的子集中,您的算法允许的唯一操作是“乘以 2”。 So it suffices to order them in ascending order.因此,将它们按升序排列就足够了。

The problem can be solved without dfs, nor is recurnece really necessary.这个问题可以不用dfs就可以解决,也不是真的需要递归。 Just order the numbers in a funny way: in descending order with respect to the number of times the number is divisible by 3, and then in ascending order.只需以一种有趣的方式对数字进行排序:按照数字可被 3 整除的次数降序排列,然后按升序排列。 So, a task for you: challenge your teacher with a solution that, once the numbers are read in, does just one instruction std::sort (or qsort , as I see you write in C), then tests the validity of the solution, and prints it.所以,给你一个任务:用一个解决方案挑战你的老师,一旦读入数字,只执行一条指令std::sort (或qsort ,正如我看到你用 C 写的那样),然后测试解决方案的有效性, 并打印出来。

Moreover, I've just proved that if a solution exists, it is unique.此外,我刚刚证明了如果存在解决方案,它就是唯一的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM