1.標題:武功祕籍
小明到X山洞探險,撿到一本有破損的武功祕籍(2000多頁!當然是僞造的)。他注意到:書的第10頁和第11頁在同一張紙上,但第11頁和第12頁不在同一張紙上。
小明只想練習該書的第81頁到第92頁的武功,又不想帶着整本書。請問他至少要撕下多少張紙帶走?
這是個整數,請通過瀏覽器提交該數字,不要填寫任何多餘的內容。
答案:7
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
int cnt;
cnt=0;
for(int i=10; i<=92; i+=2) {
cnt++;
cout<<i<<' '<<i+1<<' '<<cnt<<endl;
}
return 0;
}
2.標題:等額本金
小明從銀行貸款3萬元。約定分24個月,以等額本金方式還款。
這種還款方式就是把貸款額度等分到24個月。每個月除了要還固定的本金外,還要還貸款餘額在一個月中產生的利息。
假設月利率是:0.005,即:千分之五。那麼,
第一個月,小明要還本金 1250, 還要還利息:30000 * 0.005,總計 1400.00
第二個月,本金仍然要還 1250, 但利息爲:(30000-1250) * 0.005 總計 1393.75
請問:小明在第15個月,應該還款多少(本金和利息的總和)?請把答案金額四捨五入後,保留兩位小數。注意:32.5,一定要寫爲:32.50
通過瀏覽器提交答案,這是一個含有小數點和兩位小數的浮點數字。不要寫多餘內容(例如:多寫了“元”或添加說明文字)
答案:1312.50
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
double li,ben=1250;
for(int i=0;i<24;i++){
li=0.005*(30000-ben*i);
printf("%d %.2f\n",i+1,li+ben);
}
return 0;
}
3.標題:猜年齡
小明帶兩個妹妹參加元宵燈會。別人問她們多大了,她們調皮地說:“我們倆的年齡之積是年齡之和的6倍”。小明又補充說:“她們可不是雙胞胎,年齡差肯定也不超過8歲啊。”
請你寫出:小明的較小的妹妹的年齡。注意: 只寫一個人的年齡數字,請通過瀏覽器提交答案。不要書寫任何多餘的內容。
答案:10
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
for(int i=1;i<=100;i++){
for(int j=1;j<=100;j++){
if(i!=j&&abs(i-j)<=8&&i*j==6*(i+j)) cout<<i<<' '<<j<<endl;
}
}
return 0;
}
4.標題:大衍數列
中國古代文獻中,曾記載過“大衍數列”, 主要用於解釋中國傳統文化中的太極衍生原理。
它的前幾項是:0、2、4、8、12、18、24、32、40、50 ...
其規律是:對偶數項,是序號平方再除2,奇數項,是序號平方減1再除2。
以下的代碼打印出了大衍數列的前 100 項。int main()
{
int i;
for(i=1; i<100; i++){
if(i%2==0) //填空
printf("%d ", i*i/2);
else
printf("%d ", (i*i-1)/2);
}
printf("\n");
}請填寫劃線部分缺失的代碼。通過瀏覽器提交答案。
注意:不要填寫題面已有的內容,也不要填寫任何說明、解釋文字。
5.標題:錦標賽
如果要在n個數據中挑選出第一大和第二大的數據(要求輸出數據所在位置和值),使用什麼方法比較的次數最少?我們可以從體育錦標賽中受到啓發。
如圖【1.png】所示,8個選手的錦標賽,先兩兩捉對比拼,淘汰一半。優勝者再兩兩比拼...直到決出第一名。
第一名輸出後,只要對黃色標示的位置重新比賽即可。
下面的代碼實現了這個算法(假設數據中沒有相同值)。
代碼中需要用一個數組來表示圖中的樹(注意,這是個滿二叉樹,不足需要補齊)。它不是存儲數據本身,而是存儲了數據的下標。
第一個數據輸出後,它所在的位置被標識爲-1
//本題思路類似於間接尋址的堆排序,輸出第一大和第二大的數,即原數據不動,用各個數據的 index 進行堆排序,對於元素數據類型較大的情況下,用 index 進行間接尋址排序的話,可以減少很多數據的搬移,效率相對的要高。這裏是用 b[]記錄元素的index , a[]記錄原始數據。
//重新決出k號位置,v爲已輸出值
void pk(int* a, int* b, int n, int k, int v)
{
int k1 = k*2 + 1;
int k2 = k1 + 1;
if(k1>=n || k2>=n){
b[k] = -1;
return;
}
if(b[k1]==v)
pk(a,b,n,k1,v);
else
pk(a,b,n,k2,v);
//重新比較
if(b[k1]<0){
if(b[k2]>=0)
b[k] = b[k2];
else
b[k] = -1;
return;
}
if(b[k2]<0){
if(b[k1]>=0)
b[k] = b[k1];
else
b[k] = -1;
return;
}
if(a[b[k1]]>a[b[k2]]) //填空 //比較b[k1]與b[k2]所對應的值誰更大
b[k] = b[k1];
else
b[k] = b[k2];
}//對a中數據,輸出最大,次大元素位置和值
void f(int* a, int len)
{
int n = 1;
while(n<len) n *= 2; //建立完全二叉樹——下標範圍
int* b = (int*)malloc(sizeof(int*) * (2*n-1)); //分配存放二叉樹的數組空間
int i;
for(i=0; i<n; i++){
if(i<len)
b[n-1+i] = i;
else
b[n-1+i] = -1;
}
//從最後一個向前處理 //建大頂堆
for(i=2*n-1-1; i>0; i-=2){
if(b[i]<0){
if(b[i-1]>=0)
b[(i-1)/2] = b[i-1];
else
b[(i-1)/2] = -1;
}
else{
if(a[b[i]]>a[b[i-1]])
b[(i-1)/2] = b[i];
else
b[(i-1)/2] = b[i-1];
}
}
//輸出樹根
printf("%d : %d\n", b[0], a[b[0]]); //輸出分別爲最大元素下標、最大元素的值
//值等於根元素的需要重新pk
pk(a,b,2*n-1,0,b[0]);
//再次輸出樹根
printf("%d : %d\n", b[0], a[b[0]]); //輸出分別爲次大元素下標、次大元素的值
free(b);
}
int main()
{
int a[] = {54,55,18,16,122,17,30,9,58};
f(a,9);
}請仔細分析流程,填寫缺失的代碼。
通過瀏覽器提交答案,只填寫缺失的代碼,不要填寫已有代碼或其它說明語句等。
6.標題:猜字母
把abcd...s共19個字母組成的序列重複拼接106次,得到長度爲2014的串。
接下來刪除第1個字母(即開頭的字母a),以及第3個,第5個等所有奇數位置的字母。
得到的新串再進行刪除奇數位置字母的動作。如此下去,最後只剩下一個字母,請寫出該字母。
答案是一個小寫字母,請通過瀏覽器提交答案。不要填寫任何多餘的內容。
答案:q
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int main (){
int n=106;
string str,s="abcdefghijklmnopqrs",tmp;
while(n--) str+=s;
while(str.size()!=1){
tmp="";
for(int i=1;i<str.size();i+=2)
tmp+=str[i]; //str.replace(i,1," "); (錯誤,因爲size實時更新!)
str=tmp;
}
cout<<str;
return 0;
}
7.標題:撲克序列
A A 2 2 3 3 4 4, 一共4對撲克牌。請你把它們排成一行。
要求:兩個A中間有1張牌,兩個2之間有2張牌,兩個3之間有3張牌,兩個4之間有4張牌。
請填寫出所有符合要求的排列中,字典序最小的那個。例如:22AA3344 比 A2A23344 字典序小。當然,它們都不是滿足要求的答案。
請通過瀏覽器提交答案。“A”一定不要用小寫字母a,也不要用“1”代替。字符間一定不要留空格。
//2342A3A4
//'2'、'3'、'4'、'A'的ASC碼依次爲50,51,52,65
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int num[5];
bool judge(int a[]){
memset(num,-1,sizeof num);
for(int i=0;i<8;i++){
if(num[a[i]]!=-1) //tip!
num[a[i]]=abs(i-num[a[i]]-1);
else
num[a[i]]=i;
}
for(int i=1;i<=4;i++)
if(num[i]!=i) return false;
return true;
}
int main(){
int a[8]={2,2,3,3,4,4,1,1}; //在這裏用1代替A
do{
if(judge(a)){
for(int i=0;i<8;i++)
cout<<a[i];
cout<<endl;
}
}while(next_permutation(a,a+8));
}
8.標題:分糖果
有n個小朋友圍坐成一圈。老師給每個小朋友隨機發偶數個糖果,然後進行下面的遊戲:
每個小朋友都把自己的糖果分一半給左手邊的孩子。
一輪分糖後,擁有奇數顆糖的孩子由老師補給1個糖果,從而變成偶數。
反覆進行這個遊戲,直到所有小朋友的糖果數都相同爲止。
你的任務是預測在已知的初始糖果情形下,老師一共需要補發多少個糖果。
【格式要求】
程序首先讀入一個整數N(2<N<100),表示小朋友的人數。
接着是一行用空格分開的N個偶數(每個偶數不大於1000,不小於2)
要求程序輸出一個整數,表示老師需要補發的糖果數。
例如:輸入
3
2 2 4
程序應該輸出:
4資源約定:
峯值內存消耗 < 256M
CPU消耗 < 1000ms請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。
所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。
注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。
提交時,注意選擇所期望的編譯器類型。
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int n;
int a[105];
int judge(){
int x=a[1];
for(int i=2;i<=n;i++)
if(a[i]!=x) return 0;
return 1;
}
int main () {
int ans=0,tmp;
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
while(judge()==0) {
tmp=a[1]/2; //防數據遺失
for(int i=1;i<n;i++){
a[i]=a[i]/2+a[i+1]/2;
if(a[i]%2){
a[i]++;
ans++;
}
}
a[n]=a[n]/2+tmp;
if(a[n]%2){
a[n]++;
ans++;
}
}
cout<<ans;
return 0;
}
9.標題:斐波那契斐波那契數列大家都非常熟悉。它的定義是:
f(x) = 1 .... (x=1,2)
f(x) = f(x-1) + f(x-2) .... (x>2)對於給定的整數 n 和 m,我們希望求出:
f(1) + f(2) + ... + f(n) 的值。但這個值可能非常大,所以我們把它對 f(m) 取模。
公式參見【圖1.png】但這個數字依然很大,所以需要再對 p 求模。
【數據格式】
輸入爲一行用空格分開的整數 n m p (0 < n, m, p < 10^18)
輸出爲1個整數例如,如果輸入:
2 3 5
程序應該輸出:
0再例如,輸入:
15 11 29
程序應該輸出:
25資源約定:
峯值內存消耗 < 256M
CPU消耗 < 1000ms請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。
所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。提交時,注意選擇所期望的編譯器類型。
四十分代碼,待更新……
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
vector<long long> v;
ll n,m,p,tmp,sum=0;
void init() {
tmp=max(n,m);
v.push_back(0);
v.push_back(1);
v.push_back(1);
for(int i=3; i<=tmp; i++)
v.push_back(v[i-1]+v[i-2]);
}
int main() {
cin>>n>>m>>p;
init();
for(int i=1; i<=n; i++) {
sum=(sum+v[i])%v[m];
}
sum=sum%p;
cout<<sum<<endl;
return 0;
}
10.標題:矩陣翻硬幣
小明先把硬幣擺成了一個 n 行 m 列的矩陣。
隨後,小明對每一個硬幣分別進行一次 Q 操作。
對第x行第y列的硬幣進行 Q 操作的定義:將所有第 i*x 行,第 j*y 列的硬幣進行翻轉。
其中i和j爲任意使操作可行的正整數,行號和列號都是從1開始。
當小明對所有硬幣都進行了一次 Q 操作後,他發現了一個奇蹟——所有硬幣均爲正面朝上。
小明想知道最開始有多少枚硬幣是反面朝上的。於是,他向他的好朋友小M尋求幫助。
聰明的小M告訴小明,只需要對所有硬幣再進行一次Q操作,即可恢復到最開始的狀態。然而小明很懶,不願意照做。於是小明希望你給出他更好的方法。幫他計算出答案。【數據格式】
輸入數據包含一行,兩個正整數 n m,含義見題目描述。
輸出一個正整數,表示最開始有多少枚硬幣是反面朝上的。【樣例輸入】
2 3【樣例輸出】
1【數據規模】
對於10%的數據,n、m <= 10^3;
對於20%的數據,n、m <= 10^7;
對於40%的數據,n、m <= 10^15;
對於10%的數據,n、m <= 10^1000(10的1000次方)。資源約定:
峯值內存消耗 < 256M
CPU消耗 < 1000ms請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。
所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。注意: main函數需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要調用依賴於編譯環境或操作系統的特殊函數。
注意: 所有依賴的函數必須明確地在源文件中 #include <xxx>, 不能通過工程設置而省略常用頭文件。提交時,注意選擇所期望的編譯器類型。
以下解析摘自網絡,後文附有原文鏈接
1.很容易得出,如果一枚硬幣被翻了奇數次,那麼它原來的狀態肯定是反面朝上,所以,我們要找的就是被翻了奇數次的硬幣
2. 根據Q操作定義,我們舉個例子,對於(2,3)這個點只有在(1,1)(1,3)(2,1)(2,3)這四個點進行Q操作時才翻轉,一共翻轉了4次,通過多個例子總結不難看出,(x,y)點再所有點進行完Q操作後翻轉的次數爲a*b次,其中a爲x的約數,b爲y的約數。因此若想要這個硬幣被翻奇數次,a和b必須都得是奇數,即x和y都有奇數個約數。
先普及一個數論知識:完全平方數有奇數個約數。
那個這個問題就轉化成了——輸入兩個數n,m,設小於等於n的完全平方數的個數是a,小於等於m的完全平方數的個數是b,求a*b。那麼怎麼求小於等於n和m完全平方數的個數呢?
再普及一個知識:
那麼這個題目有轉化成了——輸入兩個數n,m,求[sqrt(n)]*[sqrt(m)]。
這樣題目就簡單很多了,只要解決兩個問題就可以
1.大數的乘法
2.大數的平方根取整
問題1解決方法:
先弄兩個代表數值的字符串s1,s2,將s1的每一位與s2相乘,存到一個整形數組裏
舉個例子s1=“123”,s2=“89”
123*89
規律:將s1[i]*s2[j]存入num[i+j+1]中,因爲num[0]要存最後進位;存完後,對num數組進行倒着計算,比如27實際上就是123*89計算中3*9=27,即把7留下2進上去
最後結果就是10947
問題2解決方法:
這個開方方法不是我想出來的,是參照了大神的一個方法
假如一個數有偶數位n,那麼這個數的方根有n/2位;如果n爲奇數,那麼方根爲(n+1)/2位。
然後,讓我們實際看一個例子,我們假設這個數就是1200
1.很明顯,它有4位,所以它的方根有2位,然後,我們通過下面的方法來枚舉出它的整數根
00*00=0<1200
10*10=100<1200
20*20=400<1200
30*30=900<1200
40*40=1600>1200
所以,這個根的十位就是3,然後,再枚舉個位
31*31=961<1200
32*32=1024<1200
33*33=1089<1200
34*34=1156<1200
所以,這個根就是34,因爲平方增長的速度還是比較快的,所以速度沒有太大問題。爲了提高速度,我們可以優化比較函數:
還拿上面的例子來說
30*30=900<1200
40*40=1600>1200
這兩個式子,一般來說,我們應該先計算3*3=9,然後在9後面添2個0再與1200比較,但由於數據量很大,添零也會消耗時間
於是我們可以計算需要加的0的數量然後用下面的方法直接比較
1.如果第i個數的平方的位數加上需要添加的零的個數之後位數與原數不相等,那麼位數大的數值大
2.如果位數相等就沒必要再添零,直接進行字符串比較即可
例如:
30*30=900<1200
40*40=1600>1200
十位是3的時候 3*3=9是1位填上兩個零後位數位3位小於1200的4位所以900<1200
十位是4的時候 4*4=16是兩位,添上兩個零後位數爲4位等於1200的四位,所以只需比較字符串16與1200的大小
很明顯在字符串中16>1200,所以1600>1200
那麼添加零的個數怎麼算呢?
假設一個數的平方根取整的位數爲n,從前往後算目前計算到了第i位,則需要添加2*(n-1-i)個零
例如:1200 平方根取整有2位,目前算到了第0位(從0開始計數)即30*30(我們算的是3*3),需要加2*(2-1-0)=2個零
原文:https://blog.csdn.net/reidsc/article/details/64924051
#include <iostream>
#include <algorithm>
using namespace std;
string StrMul(string s1,string s2) { //大數乘法
string ans;
int num[500]= {0},i,j;
for(i=0; i<s1.length(); i++) //s計算存到num中
for(j=0; j<s2.length(); j++)
num[i+j+1]+=(s1[i]-'0')*(s2[j]-'0');
for(i=s1.length()+s2.length()-1; i>0; i--) //num的處理
if(num[i]>=10) {
num[i-1]+=num[i]/10;
num[i]%=10;
}
for(int i=0; i<=s1.length()+s2.length()-1; i++) //將num數存到ans字串中,注意進位爲0的情況
if(!i&&num[i]||i)
ans.push_back(num[i]+'0');
return ans;
}
bool StrCmp(string s1,string s2,int pos) { //比較兩字符串大小,pos代表應該在s1後面填幾個零
if(s1.length()+pos!=s2.length())//如果s1位數不等於s2,
return s1.length()+pos>s2.length();
else//位數相等
return s1>s2;
}
string SqrtStr(string s) { //大數平方根取整
int len;
string ans;
if(s.length()%2==0)//長度爲偶數
len=s.length()/2;
else
len=s.length()/2+1;
for(int i=0; i<len; i++) { //一位一位的循環
ans.push_back('0');
for(int j=0; j<=9; j++) {
if(StrCmp(StrMul(ans,ans),s,2*(len-1-i)))//需要添加0的個數是2*(len-1-i)解析見上面
break;
ans[i]++;
}
ans[i]--;
}
return ans;
}
int main() {
string s1,s2;
cin>>s1>>s2;
cout<<StrMul(SqrtStr(s1),SqrtStr(s2))<<endl;
return 0;
}