2013-06-05 5 views
7

tôi đang cố gắng để giải quyết SPOJ problem "Ones and zeros":SPOJ 370 - Ones và số không (ONEZERO)

Một số nguyên dương có đại diện thập phân của họ bao gồm duy nhất của những người thân và số không, và có ít nhất một chữ số một, ví dụ 101. Nếu một số nguyên dương không có thuộc tính như vậy, một số có thể cố gắng nhân nó với một số nguyên dương để tìm hiểu xem sản phẩm có thuộc tính này hay không.

Cách tiếp cận của tôi đối với vấn đề này đơn giản là thực hiện BFS. Lấy chuỗi chỉ chứa '1' và sau đó thực hiện BFS với nó và tại mỗi bước thêm '1''0'. Theo dõi số ở dạng chuỗi và phần còn lại cho đến bây giờ. Khi số dư còn lại bằng 0, số được tìm thấy.

Sự cố của tôi là: Mã của tôi mất quá nhiều thời gian cho các trường hợp kiểm tra, ví dụ: 9999 hoặc 99999. Làm thế nào tôi có thể cải thiện thời gian chạy của thuật toán?

// Shashank Jain 
/* 
    BFS 
*/ 
#include <iostream> 
#include <cstdio> 
#include <cstring> 
#include <climits> 
#include <string> 
#include <algorithm> 
#include <vector> 
#include <cmath> 
#include <queue> 
#include <stack> 
#define LL long long int 
using namespace std; 
LL n; 
string ans; 

void bfs() 
{ 
    string str,first,second; 
    str+='1'; // number will start with '1' always 
    if(n==1) 
    { 
    ans=str; 
    return; 
    } 
    queue<pair<string,LL> >q; // pair of STRING(number) and long long int 
          // (to hold remainder till now) 
    pair<string,LL>p; 
    p=make_pair(str,1); 
    q.push(p); 
    LL rem,val,temp; 
    while(q.empty()==0) 
    { 
    p=q.front(); 
    q.pop(); 
    str=p.first; 
    val=p.second; 
    if(val==0) // remainder is zero means this is number 
    { 
     ans=str; 
     return ; 
    } 
    // adding 1 to present number  
    temp=val*10+1; 
    rem=(temp)%n; 
    firstone=str+'1'; 
    p=make_pair(firstone,rem); 
    q.push(p); 
    // adding 0 to present number  
    temp=val*10+0; 
    rem=(temp)%n; 
    secondone=str+'0'; 
    p=make_pair(secondone,rem); 
    q.push(p); 
    } 
} 

int main() 
{ 
    int t,i; 
    scanf("%d",&t); 
    while(t--) 
    { 
    scanf("%lld",&n);  
    bfs(); 
    for(i=0;i<ans.size();i++) 
    { 
     printf("%c",ans[i]);   
    } 
    printf("\n"); 
    } 
    return 0; 
} 
+0

@Christian Ammer - Cảm ơn bạn đã chỉnh sửa! –

+0

Bạn được chào đón, luôn luôn là một ý tưởng hay để đưa mô tả sự cố vào câu hỏi và định dạng mã một cách proberly. –

Trả lời

6

Tôi vừa giải quyết được sự cố. Tôi sẽ không gửi đoạn của tôi, nhưng tôi sẽ cung cấp cho các điểm tại sao mã của bạn là chậm

  1. Như sukunrt nói rằng bạn cần phải giữ một mảng thăm của n kích thước, nơi bạn có thể đánh dấu các module hiện thu được như thăm để rằng bạn không ghé thăm nó một lần nữa, bởi vì nếu bạn đang ở một mô-đun đã truy cập bạn không cần phải xem xét một phần của chuỗi thu được cho đến bây giờ vì nó chỉ làm cho số lượng lớn hơn (chúng ta cần tối thiểu), tức là nó có nghĩa là một khi bạn truy cập vào một mô-đun bạn nói x sau đó bạn tìm thấy số ít nhất bao gồm 0 và 1 cung cấp cho x phần còn lại khi chia cho n.

  2. Bạn luôn chuyển chuỗi để thu được cho trẻ, không chỉ tăng bộ nhớ mà còn cả thời gian nữa. Để tránh điều này, chỉ cần thêm hai mảng nữa, hãy nói value[]parent[] cả hai kích thước n.

    parent[i] lưu trữ mô-đun gốc của mô-đun i.

    value[i] các cửa hàng là bit hiện tại tương ứng với mô-đun i (0 < = i < n).

    Cuối cùng, bạn chỉ có thể quay lại để tạo thành toàn bộ số chỉ dành cho modulus = 0.

    Ngoài ra sau khi thực hiện thay đổi, mã của bạn sẽ cho WA vì trước tiên bạn phải đẩy con thu được bằng cách gắn '0' ở cuối và sau đó con có được bằng cách nối '1' ở cuối. (Bạn có thể tự mình chứng minh điều đó).

+0

tôi đã hiểu về điểm 2. bạn có thể giải thích thêm chút nữa không? –

+1

@shashank Tôi vừa đưa ra một phương pháp để tránh bỏ qua các đối số chuỗi cho các nút con mà bạn đẩy vào hàng đợi mà tôi có thể giải thích chi tiết nhưng tôi không nghĩ nó phù hợp với chú thích – sashas

+0

@ Migdal-i giải mã .. cảm ơn nó đã được chấp nhận !! điểm 2 là quá tốt và dễ bị lãng quên khi thực hiện! Cảm ơn ! –

4

Đây là gợi ý. suy nghĩ về nó theo cách này:

Giả sử số mà bạn muốn là X. X mod N = 0.

Vì vậy, bạn cần phải chỉ lưu trữ N khẳng định ví dụ: 0-n-1. Bắt đầu bằng 1. và thực hiện bfs. Bạn cần phải loại bỏ các chi nhánh có phần còn lại như trước. Tôi sẽ để lại bằng chứng cho bạn.

+0

đây chính xác là những gì tôi đang làm ..popping từ hàng đợi loại bỏ các chi nhánh và chỉ xem xét chi nhánh hiện tại chạy vào !! –

+3

bạn có chắc chắn không. tôi không nghĩ rằng bạn đang tiết kiệm các phần còn lại được tìm thấy ở bất cứ đâu. – sukunrt

+0

nếu 1 == 101 (mod N) bạn đang xếp hàng 101 trẻ em trong hàng đợi. – sukunrt