猜燈謎
A村的元宵節燈會上有一迷題:
請猜謎 * 請猜謎 = 請邊賞燈邊猜
小明想,一定是每個漢字代表一個數字,不同的漢字代表不同的數字。
請你用計算機按小明的思路算一下,然後提交“請猜謎”三個字所代表的整數即可。
請嚴格按照格式,通過瀏覽器提交答案。
注意:只提交一個3位的整數,不要寫其它附加內容,比如:說明性的文字。
答案:897
直接for加判斷就好
加密
在對文本進行簡單加密的時候,可以選擇用一個n位的二進制數,對原文進行異或運算。
解密的方法就是再執行一次同樣的操作。
加密過程中n位二進制數會循環使用。並且其長度也可能不是8的整數倍。
下面的代碼演示瞭如何實現該功能。
請仔細閱讀,填寫空缺的代碼(下劃線部分)。
注意:請把填空的答案(僅填空處的答案,不包括題面)存入考生文件夾下對應題號的“解答.txt”中即可。
直接寫在題面中不能得分。
void f(char* buf, unsigned char* uckey, int n)
{
int i;
for(i=0; i<n; i++)
buf[i] = buf[i] ^ uckey[i];
}
int main(int argc, char* argv[])
{
char p[] = "abcd中國人123"; // 待加密串
char* key = "11001100010001110"; //以串的形式表達的密匙,運算時要轉換爲按位存儲的形式。
int np = strlen(p);
int nk = strlen(key);
unsigned char* uckey = (unsigned char*)malloc(np);
// 密匙串需要按位的形式循環拼入 uckey中
int i;
for(i=0; i<np*8; i++)
{
if(key[i%nk]=='1')
____________________________________________; // 填空1
else
____________________________________________; // 填空2
}
f(p, uckey, strlen(p));
f(p, uckey, strlen(p));
printf("%s\n", p);
free(uckey);
return 0;
}
答案:
// 密匙串需要按位的形式循環拼入 uckey中
int i;
for(i=0; i<np*8; i++)
{
if(key[i%nk]=='1')
{
uckey[i / 8] = (uckey[i / 8] << 1) | 0x01; // 填空1
//uckey[i/8] |= (unsigned char)0x80 >> (i%8); //標準答案
}
else
{
uckey[i / 8] = uckey[i / 8] << 1; // 填空2
//uckey[i/8] &= ~((unsigned char)0x80 >> (i%8)); //標準答案
}
}
公倍數
爲什麼1小時有60分鐘,而不是100分鐘呢?這是歷史上的習慣導致。
但也並非純粹的偶然:60是個優秀的數字,它的因子比較多。
事實上,它是1至6的每個數字的倍數。即1,2,3,4,5,6都是可以除盡60。
我們希望尋找到能除盡1至n的的每個數字的最小整數。
不要小看這個數字,它可能十分大,比如n=100, 則該數爲:
69720375229712477164533808935312303556800
請編寫程序,實現對用戶輸入的 n (n<100)求出1~n的最小公倍數。
例如:
用戶輸入:
6
程序輸出:
60
用戶輸入:
10
程序輸出:
2520
要求考生把所有函數寫在一個文件中。調試好後,存入與考生文件夾下對應題號的“解答.txt”中即可。
相關的工程文件不要拷入。
對於編程題目,要求選手給出的解答完全符合ANSI C標準,不能使用c++特性;
不能使用諸如繪圖、中斷調用等硬件相關或操作系統相關的API。
答案:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 105;
int n;
int a[N][50];
int b[N] = {0};
void multiply()
{
int i,j,k;
memset(a,0,sizeof(a));
for(i=3; i<=100; i++)
{
/*
下面的是直接按平常的乘法,乘數的一位乘以被乘數的每一位並處理進位;另外是乘數整體乘以被乘數的每一位最後統一處理進位
*/
int temp = 0;
a[i][0] = 1;//很重要
for(j=2; j<=i; j++)
{
int c = 0;
for(k=0; k<50; k++)//最大不超過160位 ,安的是100!,最後除以3等50
{
temp = a[i][k]*b[j] + c;
a[i][k] = temp%1000;
c = temp/1000;
}
}
}
}
void printData(int n)
{
int i,j,k;
for(i=49; i>=0; i--)
if(a[n][i])
break;
cout<<a[n][i];//第一個不輸出前導0
for(j=i-1; j>=0; j--)
printf("%03d",a[n][j]);
cout<<endl;
}
int main()
{
int i, j, k;
for(i=0; i<N; i++)
b[i] = i;
for(i=2; i<N; i++)
for(j=i+1; j<=N; j++)
{
if(b[j]%b[i]==0)
b[j] /= b[i];
//cout<<b[j]<<endl;
}
//for(i=0; i<100; i++)
// cout<<b[i]<<endl;
//while(1);
multiply();
while(cin>>n)
{
if(n==1||n==2)
{
cout<<n<<endl;
continue;
}
printData(n);
}
return 0;
}
高僧鬥法
古時喪葬活動中經常請高僧做法事。儀式結束後,有時會有“高僧鬥法”的趣味節目,以舒緩壓抑的氣氛。
節目大略步驟爲:先用糧食(一般是稻米)在地上“畫”出若干級臺階(表示N級浮屠)。又有若干小和尚隨機地“站”在某個臺階上。最高一級臺階必須站人,其它任意。
兩位參加遊戲的法師分別指揮某個小和尚向上走任意多級的臺階,但會被站在高級臺階上的小和尚阻擋,不能越過。兩個小和尚也不能站在同一臺階,也不能向低級臺階移動。
兩法師輪流發出指令,最後所有小和尚必然會都擠在高段臺階,再也不能向上移動。輪到哪個法師指揮時無法繼續移動,則遊戲結束,該法師認輸。
對於已知的臺階數和小和尚的分佈位置,請你計算先發指令的法師該如何決策才能保證勝出。
輸入數據爲一行用空格分開的N個整數,表示小和尚的位置。臺階序號從1算起,所以最後一個小和尚的位置即是臺階的總數。(N<100, 臺階總數<1000)
輸出爲一行用空格分開的兩個整數: A B, 表示把A位置的小和尚移動到B位置。若有多個解,輸出A值較小的解,若無解則輸出-1。
例如:
用戶輸入:
1 5 9
則程序輸出:
1 4
再如:
用戶輸入:
1 5 8 10
則程序輸出:
1 3
資源約定:
峯值內存消耗 <64M
CPU消耗 < 1000ms
答案:(好像用到了尼姆定理)
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<limits.h>
using namespace std;
int t[1111];
int b[1111];
int c[1111];
void xiazi(int sum)
{
for(int i= 1; i< sum; i++)
for(int j= 1; j<= b[i]; j++)
{
int xixi;
if(i%2)
xixi= c[i]^(b[i]-j);
else
xixi= c[i-1]^(b[i-1]+j);
if(xixi==0)
{
printf("%d %d\n",t[i],t[i]+j);
return;
}
}
printf("-1\n");
return;
}
int main()
{
int a;
char ch;
scanf("%d%c",&a,&ch);
int sum= 1;
t[sum]= a;
c[0]= 0;
while(ch!='\n')
{
scanf("%d%c",&a,&ch);
sum++;
t[sum]= a;
}
sort(t+1, t+ sum + 1);
for(int i= 2; i<= sum; i++)
{
b[i-1]= t[i]- t[i-1] - 1;
if((i-1)%2)
c[0]= c[0]^b[i-1];
}
for(i= 1; i< sum; i+=2)
c[i]= c[0]^b[i];
if(c[0]==0)
printf("-1\n");
else
xiazi(sum);
return 0;
}
方格填數
如下圖所示,3 x 3 的格子中填寫了一些整數。
+–*–+–+
|10* 1|52|
+–**–+
|20|30* 1|
*–+
| 1| 2| 3|
+–+–+–+
我們沿着圖中的星號線剪開,得到兩個部分,每個部分的數字和都是60。
本題的要求就是請你編程判定:對給定的m x n 的格子中的整數,是否可以分割爲兩個部分,使得這兩個區域的數字和相等。
如果存在多種解答,請輸出包含左上角格子的那個區域包含的格子的最小數目。
如果無法分割,則輸出 0。
輸入格式
程序先讀入兩個整數 m n 用空格分割 (m,n<10)。
表示表格的寬度和高度。
接下來是n行,每行m個正整數,用空格分開。每個整數不大於10000。
輸出格式
輸出一個整數,表示在所有解中,包含左上角的分割區可能包含的最小的格子數目。
樣例輸入1
3 3
10 1 52
20 30 1
1 2 3
樣例輸出1
3
樣例輸入2
4 3
1 1 1 1
1 30 80 2
1 1 1 100
樣例輸出2
10
答案:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 10
int map[N][N]={0};
int vis[N][N];
int count=0;//記錄解得節點數
int mincount=1000;//記錄最小的節點數
int result=0;//記錄搜索過程中的結果和
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int half;
void mysearch(int i,int j,int n,int m);//回溯法進行搜索
int main()
{
int m,n; //n:行,m:列
int i,j,sum=0;
int max=-1;
scanf("%d%d",&m,&n);
for(i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
scanf("%d",&map[i][j]);
if (max<map[i][j])
{
max=map[i][j];
}
sum+=map[i][j];
}
}
half=sum/2;
if(max>half) //最大值大於全體數字的一般,無解
{
printf("0\n");
return 0;
}
memset(vis,0,sizeof(vis));
i=j=0;
mysearch(i,j,n,m);
system("pause");
return 0;
}
void mysearch(int i,int j,int n,int m) //回溯法進行搜索
{
int x,y,newx,newy;
int r;
x=i;
y=j;
if (i<0 || i>=n || j<0 || j>=m)
{
return;
}
if(vis[x][y]==0 && result+map[x][y] <= half)
{
printf("(%d,%d)\n",x,y);
result+=map[x][y];
vis[x][y]=1;
count++;
}
else
{
return;
}
if (result==half)
{
if (count>n*m/2)
{
printf("%d\n",n*m-count);
}
else
{
printf("%d\n",count);
}
exit(0);
}
for (r=0;r<4;r++)
{
newx=x+dx[r];
newy=y+dy[r];
mysearch(newx,newy,n,m);
}
vis[x][y]=0;
result=result-map[x][y];
count--;
return;
}