1 Sifferkryss Till vänster i figuren ovan ser du ett sifferkryss, där de tomma rutorna ska fyllas i, med talen 1... 9, så att alla summor stämmer. Varje tal 1...9 ska finnas med precis en gång i lösningen, som till höger i figuren. Skriv ett program som hämtar in aktuella summor från filen summor.txt, 6 tal, först talen i ytterkolumnen, uppifrån och ned, sedan den undre raden, från vänster till höger, 21,15,9,22,15,8 i vårt exempel. Programmet ska i en tabell skriva ut de 9 talen, som för vårt exempel ger 9 8 4 7 5 3 6 2 1 Håkan Strömberg 1 KTH STH
P P P P P Figur 1: 2 Polisövervakning Inför pingsthelgen förstärker polisen trafikövervakningen! #...#.#...###.#... Strängen ovan beskriver en 19 km lång vägsträcka, 1 km per tecken. En utplacerad polis kan övervaka en sträcka av tre kilometer, dels den plats (kilometer) där han är placerad, plus en kilometer åt vart håll. Det är endast de delar av hela sträckan, som är markerad med punkter, som ska övervakas. Poliser kan dock placeras var som helst utefter hela sträckan. Skriv ett program som läser in en sträng (< 80 tecken) från filen vag.txt och som bestämmer det minsta antal poliser som behövs för att övervaka önskade delar av hela vägsträckan. Här är en lösning av vårt exempel, där vi ser var poliserna (P) är placerade (se även figur 1): #...#.#...###.#... --P--P---P----P--P- Ett körningsexempel: Det behövs som minst 5 poliser Håkan Strömberg 2 KTH STH
3 Samma summa För flera mängder av konsekutiva tal från 1 till n kan man dela upp mängden i två mängder där summan av elementen i de två mängderna är lika. För n = 3 finns endast den triviala uppdelningen {3} och {1,2}, båda med summan 3. För n = 7 med talen {1, 2, 3, 4, 5, 6, 7} finns fyra möjligheter, nämligen {1,6,7} {2,3,4,5} {2,5,7} {1,3,4,6} {3,4,7} {1,2,5,6} {1,2,4,7} {3,5,6} Skriv ett program som för n 39 bestämmer antalet möjligheter att dela upp de 1...n talen i två mängder med samma summa. Om ingen lösning kan hittas ska programmet skriva ut 0. Ett par körningsexempel: n? 24 93846 n? 31 8273610 Om ditt program klarar av att leverera korrekt resultat inom loppet av ett par sekunder för n > 30 får du en extra poäng! Observera att det inte är tillåtet för programmet att innehålla en tabell med värden du beräknat under tentan. Håkan Strömberg 3 KTH STH
1 Sifferkryss 2 int vald[10],tal[10],sum[6],antal=0; 3 4 int test(void){ 5 int ok=1; 6 if(tal[1]+tal[2]+tal[3]!=sum[0]) ok=0; 7 if(tal[4]+tal[5]+tal[6]!=sum[1]) ok=0; 8 if(tal[7]+tal[8]+tal[9]!=sum[2]) ok=0; 9 if(tal[1]+tal[4]+tal[7]!=sum[3]) ok=0; 10 if(tal[2]+tal[5]+tal[8]!=sum[4]) ok=0; 11 if(tal[3]+tal[6]+tal[9]!=sum[5]) ok=0; 12 return ok; 13 } 14 15 void solve(int nr){ 16 int i; 17 if(nr==9){ 18 if(test()){ 19 antal++; 20 printf("lösning %d:\n",antal); 21 for(i=1;i<=9;i++){ 22 printf("%2d",tal[i]); 23 if(i%3==0) 24 printf("\n"); 25 } 26 } 27 } 28 else 29 for(i=1;i<=9;i++) 30 if(!vald[i]){ 31 tal[nr+1]=i; 32 vald[i]=1; 33 solve(nr+1); 34 vald[i]=0; 35 } 36 } 37 38 int main(void){ 39 FILE *fil; 40 int i; 41 fil=fopen("summor.txt","rt"); 42 for(i=0;i<6;i++) 43 fscanf(fil,"%d",&sum[i]); 44 fclose(fil); 45 solve(0); 46 } Håkan Strömberg 4 KTH STH
2 Polisövervakning 2 #include <string.h> 3 int main(void){ 4 char vag[103]; 5 FILE *fil; 6 int i,antal=0,langd; 7 8 fil=fopen("vag2.txt","rt"); 9 fscanf(fil,"%s",vag); 10 11 langd=strlen(vag); 12 strcat(vag,"##"); 13 14 for(i=0;i<langd;i++) 15 if(vag[i]==. ){ 16 vag[i+1]= # ; 17 vag[i+2]= # ; 18 antal++; 19 } 20 printf("antal poliser %d\n",antal); 21 } 2 #include <limits.h> 3 #include <string.h> 4 5 int langd,min=int_max; 6 7 int test(int aker[]){ 8 int i; 9 for(i=1;i<=langd;i++) 10 if(aker[i]==0) 11 return 0; 12 return 1; 13 } 14 15 void solve(int aker[],int start,int antal){ 16 int i,t1,t2,t3; 17 18 if(test(aker)){ 19 if(antal<min) 20 min=antal; 21 } 22 else{ 23 for(i=start;i<langd;i++){ 24 t1=aker[i-1];aker[i-1]=2; 25 t2=aker[i]; aker[i]=2; 26 t3=aker[i+1];aker[i+1]=2; 27 solve(aker,i+2,antal+1); 28 aker[i-1]=t1; 29 aker[i]=t2; 30 aker[i+1]=t3; 31 } 32 } 33 } Håkan Strömberg 5 KTH STH
1 int main(void){ 2 int aker[103],i; 3 FILE *fil; 4 char tmp[101]; 5 6 fil=fopen("vag1.txt","rt"); 7 fscanf(fil,"%s",tmp); 8 9 langd=strlen(tmp); 10 for(i=0;i<strlen(tmp);i++){ 11 if(tmp[i]== # ) aker[i+1]=1; 12 if(tmp[i]==. ) aker[i+1]=0; 13 } 14 aker[0]=1; 15 aker[langd+1]=1; 16 aker[langd+2]=1; 17 for(i=0;i<=langd+2;i++) 18 printf("%d",aker[i]); 19 printf("\n"); 20 solve(aker,1,0); 21 printf("%d\n",min); 22 } Håkan Strömberg 6 KTH STH
3 Samma summa 1 // Backtracking. Ej speciellt snabbt 2 // Klarar 30 på överskådlig tid 3 4 #include <stdio.h> 5 #include <string.h> 6 7 void solve(int tot,int start,int n,int max,int vald[],int *antal){ 8 int i; 9 if(tot==max) 10 (*antal)++; 11 else 12 if(tot<max) 13 for(i=start;i<=n;i++) 14 if(!vald[i]){ 15 vald[i]=1; 16 solve(tot+i,i+1,n,max,vald,antal); 17 vald[i]=0; 18 } 19 } 20 21 int main(void){ 22 int n,antal=0,vald[40]={0}; 23 printf("n? "); 24 scanf("%d",&n); 25 if(n%4==1 n%4==2) 26 printf("antal %d\n",antal); 27 else{ 28 solve(0,1,n,n*(n+1)/4,vald,&antal); 29 printf("antal %d\n",antal/2); 30 } 31 } 2 int dyn[1024]; 3 int main(void) { 4 int s,n,i,j; 5 printf("n? "); 6 scanf("%d",&n); 7 s = n*(n+1); 8 if (s%4!=0) 9 printf("0\n"); 10 else{ 11 s=s/4; 12 dyn[0]=1; 13 for(i=1; i<=n; i++) 14 for (j=s; j>=i; j--) 15 dyn[j]=dyn[j]+dyn[j-i]; 16 printf("%d\n",dyn[s]/2); 17 } 18 } Håkan Strömberg 7 KTH STH