একটি বিট মহাদেশ তৈরি করুন


11

আসুন কল্পনা করুন আমাদের বিটসের একটি ম্যাট্রিক্স রয়েছে (এতে কমপক্ষে একটি রয়েছে 1):

0 1 0 1 1 0 1 0 0 1 0
0 1 0 1 0 0 1 0 1 1 0
0 0 1 0 1 1 0 1 0 1 0
1 1 0 0 1 0 0 1 1 0 1
0 0 0 1 0 1 1 0 0 1 0

আমরা এই ম্যাট্রিক্সের কিছু বিট সেট করতে চাই যাতে এটি একটি সংক্ষিপ্ত প্রসারণ গঠন 1করে, যার 1মধ্যে প্রত্যক্ষ বা অপ্রত্যক্ষভাবে 1অরথোগোনাল আন্দোলনের মাধ্যমে একে অপরের সাথে সংযুক্ত থাকে :

0 1 1 1 1 1 1 0 0 1 0
0 1 0 1 0 0 1 0 1 1 0
0 1 1 0 1 1 1 1 0 1 0
1 1 0 0 1 0 0 1 1 1 1
0 0 0 1 1 1 1 0 0 1 0

(আপনি 1আপনার ব্রাউজারের "সন্ধান" বৈশিষ্ট্যটি অনুসন্ধান করে এটি আরও স্পষ্ট দেখতে পাচ্ছেন ))

তবে আমরা যে বিট সেট করেছিলাম তাও কম করতে চাই।

কাজটি

বিটস বা বুলিয়ানগুলির একটি ম্যাট্রিক্স (বা অ্যারের অ্যারে) দেওয়া, ন্যূনতম সংখ্যার বিটগুলি প্রদান করুন যা গুলিগুলির একটি ধারাবাহিক মহাদেশ তৈরি করতে সেট করতে হবে 1। ম্যাট্রিক্সের একটি সেট বিট থেকে অন্য সেট বিটগুলিতে কেবল একটি অर्थোগোনাল দিক ভ্রমণ করেই ম্যাট্রিক্সের অন্য সেটটিতে পৌঁছানো সম্ভব।

এটি , তাই সংক্ষিপ্ততম বৈধ জমা (বাইটগুলিতে পরিমাপ করা) জয়ী।

পরীক্ষার কেস

0 1 0 1 1 0 1 0 0 1 0
0 1 0 1 0 0 1 0 1 1 0
0 0 1 0 1 1 0 1 0 1 0
1 1 0 0 1 0 0 1 1 0 1
0 0 0 1 0 1 1 0 0 1 0
=> 6

1 0 0 0 0 0 1 0 0
1 1 0 0 1 1 1 0 0
1 1 1 0 1 1 1 1 1
0 1 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1
0 1 0 0 0 0 1 1 0
1 0 0 0 0 0 1 0 0
=> 4

0 0 0 1 1 1 0 1 1
0 0 1 0 0 0 0 1 0
0 0 1 1 1 1 1 1 0
1 1 0 0 1 1 0 0 0
0 0 1 1 1 0 0 1 1
0 1 1 1 0 0 0 0 0
1 1 1 0 0 1 1 1 0
1 1 1 0 1 1 0 1 1
0 0 0 0 1 0 0 0 1
1 1 0 0 1 1 0 1 1
0 0 0 0 0 0 0 1 0
0 1 1 1 1 0 0 0 0
0 0 0 1 1 0 0 0 1
0 1 0 0 1 0 1 1 0
0 1 1 1 0 0 0 0 1
=> 8

1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
=> 0

1
এর জন্য আরও কিছুটা ব্যাখ্যা করা দরকার। ম্যাট্রিক্সের "কন্টিগুয়াস ব্লব" কী?
NoOneIs এখানে

11
যেহেতু সমস্যাটি এনপি-হার্ড হিসাবে পরিচিত, এটি দ্রুত-অ্যালগরিদমের পক্ষে ভাল সমস্যা নয় ।
পিটার টেলর

1
@ পিটার টেলর এবং এসওলিংফ্রুট এনপি-
হার্ডনেস

1
পিটার টেলর এবং হাইপার নিউট্রিনোর মন্তব্য এবং এই প্রশ্নের বর্তমানে কোন উত্তর নেই এই আলোকে আমি স্কোরিং পদ্ধতিটি কোড-গল্ফে পরিবর্তন করছি ।
3:30 এ ফল ফলবান

1
1ম্যাট্রিক্স না থাকলে আমাদের কী করা উচিত ?
কোলেরা সু

উত্তর:


1

সি (জিসিসি), 308 306 বাইট

ফাংশন fপায় (height, width, flattened array, pointer to ans), এবং আয় পয়েন্টার দ্বারা উত্তর দিন।

তাহলে সেখানে কোন 1ম্যাট্রিক্স, এটা ফিরে আসবে 0

#define v A[i]
N,M,K,R,C,T,i,*A;s(x,y){i=x*M+y;if(!(x<0|y<0|x>=N|y>=M|v^1))v=2,s(x,y+1),s(x,y-1),s(x+1,y),s(x-1,y);}g(i){if(C<R){if(i^K){g(i+1);if(!v)C+=v=1,g(i+1),v=0,C--;}else{T=1;for(i=0;i<K&&!v;i++);s(i/M,i%M);for(i=0;i<K;i++)T&=v^1,v=!!v;if(T)R=C;}}}f(n,m,a,b)int*a,*b;{K=R=(N=n)*(M=m),A=a;g(0);*b=R;}

এটি অনলাইন চেষ্টা করুন!

Ungolfed:

N,M,R,C,T,i,*A; // height, width, result, recursion depth

s(x,y)
{ // depth first search: replace all 1 in the same connected component with 2
    i=x*M+y;
    if(!(x<0|y<0|x>=N|y>=M|A[i]^1)) { // check if out of boundary
        A[i]=2;
        s(x, y+1),s(x, y-1),s(x+1, y),s(x-1, y);
    }
}

g(i)
{ // enumerate all posible solutions
    if(C<R) {
        if(i!=N*M) {
            g(i+1);      // nothing change for this entry
            if (!A[i]) { // set the entry to 1
                C++, A[i]=1;
                g(i+1);
                C--, A[i]=0;
            }
        }
        else {
            T=1;
            for (i=0; i<N*M && !A[i]; i++); // find first non-zero entry
            s(i/M, i%M);     // replace the connected component
            for (i=0; i<N*M; i++) {
                T&=A[i]!=1;   // check if no other components
                A[i]=!!A[i]; // change 2s back to 1
            }
            if (T) R=C;      // update answer
        }
    }
}

f(n,m,a,b)int*a,*b;{
    R=(N=n)*(M=m), A=a;
    g(0);
    *b=R;
}

0

পাইথন 2 , 611 বাইট

একটি সম্পূর্ণ প্রোগ্রাম যা ব্যবহারকারীদের ইনপুটটির মাধ্যমে তালিকার একটি তালিকা নেয়। অ্যারেতে দ্বীপের সংখ্যা নির্ধারণ করে Iএবং এটি dগণনা করে। শেষে লুপটি সমস্ত সম্ভাবনার মধ্য দিয়ে গণনা করে আপনি যেখানে 0এস পরিবর্তন করতে পারবেন 1তারপরে যদি সেখানে একটি দ্বীপ বামে 1থাকে তবে তালিকায় যুক্ত হওয়া সংখ্যার সংখ্যা রয়েছে C। সেই তালিকার সর্বনিম্ন হ'ল কোনও দ্বীপকে সংযুক্ত করার জন্য প্রয়োজনীয় ন্যূনতম বিট ফ্লিপ number এটি খুব ধীরগতির অ্যালগরিদম তাই এটি s০-এর দশকের নীচে দেওয়া টেস্ট কেসগুলি চালায় না (আমি আর চেষ্টা করিনি) তবে আমি কয়েকটি ছোট (x 5x5) পরীক্ষার ক্ষেত্রে চেষ্টা করেছি এবং মনে হচ্ছে এটি সঠিকভাবে কাজ করছে। আমি এই পৃষ্ঠা থেকে দ্বীপ গণনা অ্যালগরিদম পেয়েছি ।

from itertools import*
def d(g,i,j,v):
 v[i][j],R,C=1,[-1,1,0,0],[0,0,-1,1]
 for k in range(4):
	if len(g)>i+R[k]>=0<=j+C[k]<len(g[0]):
	 if v[i+R[k]][j+C[k]]<1and g[i+R[k]][j+C[k]]:v=d(g,i+R[k],j+C[k],v)
 return v
def I(g):
 w=len(g[0])
 v,c=[w*[0]for r in g],0
 for i in range(len(g)*w):
	if v[i/w][i%w]<1and g[i/w][i%w]>0:v=d(g,i/w,i%w,v);c+=1
 return c           
g=input()
C=[]
for p in [list(t)for t in product([0,1],repeat=sum(r.count(0)for r in g))]:
 h,G,x=0,[r[:]for r in g],len(g[0])
 for i in range(x*len(G)):
	if G[i/x][i%x]<1:h+=p[0];G[i/x][i%x]=p[0];del p[0]
 if I(G)<2:
	C.append(h)
print min(C)

এটি অনলাইন চেষ্টা করুন!

আমি কয়েকটি জিনিস অনুকূলিত করার আগে প্রিগল্ফড সংস্করণ:

from itertools import*
def d(g,i,j,v):
    v[i][j]=1
    R=[-1,1,0,0]
    C=[0,0,-1,1]
    for k in range(4):
        if len(g)>i+R[k]>=0<=j+C[k]<len(g[0]):
            if v[i+R[k]][j+C[k]]<1:
                if g[i+R[k]][j+C[k]]:
                    v=d(g,i+R[k],j+C[k],v)
    return v
def I(g):
    w=len(g[0])
    v=[[0]*w for r in g]
    c=0
    for i in range(len(g)):
        for j in range(w):
            if v[i][j]<1and g[i][j]>0:
                v=d(g,i,j,v)
                c+=1
    return c           
g=input()
z=sum(r.count(0)for r in g)
f=[list(t)for t in product('01',repeat=z)]
C=[]
for p in f:
    h=0
    G=[r[:]for r in g]
    x=len(G[0])
    for i in range(x*len(G)):
        exec('h+=int(p[0]);G[i/x][i%x]=int(p[0]);del p[0]'*(G[i/x][i%x]<1))
    if I(G)<2:
        C.append(h)
print min(C)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.