7-6 隨機輸一次 (20分)
現要求你編寫一個控制贏面的程序,根據對方的出招,給出對應的贏招。但是!為了不讓對方意識到你在控制結果,你需要隔 K 次輸一次,其中 K 是系統設定的隨機數。
輸入格式:
輸入首先在第一行給出正整數 N(≤10),隨后給出 N 個系統產生的不超過 10 的正隨機數 { K1,K2,⋯,KN },數字間以空格分隔。這意味着第 i(i=0,1,⋯,N−1)次輸局之后應該隔 Ki+1 次再讓下一個輸局。如果對方出招太多,則隨機數按順序循環使用。例如在樣例中,系統產生了 3 個隨機數 {2, 4, 1},則你需要:贏 2 次,輸 1 次;贏 4 次,輸 1 次;贏 1 次,輸 1 次;然后再次回到第 1 個隨機數,贏 2 次,輸 1 次。
之后每行給出對方的一次出招:“ChuiZi”代表“錘子”、“JianDao”代表“剪刀”、“Bu”代表“布”。“End”代表輸入結束,這一行不要作為出招處理。輸入保證對方至少出了一招。
輸出格式:
對每一個輸入的出招,按要求輸出贏或輸局的招式。每招占一行。
輸入樣例:
3 2 4 1
ChuiZi
JianDao
Bu
JianDao
Bu
ChuiZi
ChuiZi
ChuiZi
JianDao
Bu
JianDao
Bu
ChuiZi
End
輸出樣例:
Bu
ChuiZi
ChuiZi
ChuiZi
JianDao
Bu
Bu
JianDao
ChuiZi
ChuiZi
ChuiZi
JianDao
JianDao
思路
判斷flag是否等於a[cnt%N],這樣模擬的思路最簡單。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e6+10;
int a[100];
void win(string x) {
if (x == "ChuiZi") cout << "Bu\n";
else if (x == "JianDao") cout << "ChuiZi\n";
else cout << "JianDao\n";
}
void lose(string x) {
if (x == "ChuiZi") cout << "JianDao\n";
else if (x == "JianDao") cout << "Bu\n";
else cout << "ChuiZi\n";
}
int main() {
// freopen("in.txt","r",stdin);
int N;
cin>>N;
for (int i=0;i<N;i++) {
cin>>a[i];
}
int flag=0,cnt=0;
string s;
while (cin>>s&&s!="End") {
if (flag==a[cnt%N]) {
lose(s);
flag=0;
cnt++;
} else {
win(s);
flag++;
}
}
return 0;
}
7-7 階乘的非零尾數 (20分)
7-7 階乘的非零尾數 (20分)
“求 N 階乘末尾的第一個非零數字”是一道常見的企業筆試題。這里我們略微做個變化,求 N 階乘末尾的第一個非零 K 位數,同時輸出末尾有多少個零。
輸入格式:
輸入給出一個不超過 107 的正整數 N 和要求輸出的位數 0<K<10。
輸出格式:
在一行中輸出 N 階乘末尾的第一個非零 K 位數(注意前導零也要輸出)、以及末尾 0 的個數,其間以 1 個空格分隔。
輸入樣例:
18 5
輸出樣例:
05728 3
思路
先把所有的5和2剔除,然后把漏掉的5 或 2再乘上去。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const long long MAXN = 1e6 + 10;
int main()
{
// freopen("in.txt", "r", stdin);
long long N, K;
cin >> N >> K;
long long base = 1;
for (long long i = 0; i < K; i++)
{
base *= 10;
}
long long cnt2 = 0, cnt5 = 0, num = 1;
for (long long i = 1; i <= N; i++)
{
long long m = i;
while (m % 5 == 0) { m /= 5; cnt5++; }
while (m % 2 == 0) { m/=2; cnt2++; }
num*=m;
num%=base;
}
long long cnt=min(cnt2,cnt5);
for (long long i=0;i<cnt2-cnt;i++) { num=2ll*num%base; }
for (long long i=0;i<cnt5-cnt;i++) { num=5ll*num%base; }
long long tmp=num,bits=0;
while (tmp) {
bits++;
tmp/=10;
}
for (long long i=0;i<K-bits;i++) { cout<<"0"; }
cout<<num<<" "<<cnt<<endl;
return 0;
}
7-8 三足鼎立 (25分)
當三個國家中的任何兩國實力之和都大於第三國的時候,這三個國家互相結盟就呈“三足鼎立”之勢,這種狀態是最穩定的。
現已知本國的實力值,又給出 n 個其他國家的實力值。我們需要從這 n 個國家中找 2 個結盟,以成三足鼎立。有多少種選擇呢?
輸入格式:
輸入首先在第一行給出 2 個正整數 n(2≤n≤105)和 P(≤109),分別為其他國家的個數、以及本國的實力值。隨后一行給出 n 個正整數,表示n 個其他國家的實力值。每個數值不超過 109,數字間以空格分隔。
輸出格式:
在一行中輸出本國結盟選擇的個數。
輸入樣例:
7 30
42 16 2 51 92 27 35
輸出樣例:
9
樣例解釋:
能聯合的另外 2 個國家的 9 種選擇分別為:
{16, 27}, {16, 35}, {16, 42}, {27, 35}, {27, 42}, {27, 51}, {35, 42}, {35, 51}, {42, 51}。
思路
- 如果p不是最大,則滿足條件的是小於a[i]+p的數
- 如果p是最大 , 則滿足條件的是大於p-a[i]的數
用lower_bound是為了多計入一位,這樣避免x==y,x-y=0。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e5+10;
long long a[MAXN];
int main() {
// freopen("in.txt","r",stdin);
long long N,P;
cin>>N>>P;
for (int i=0;i<N;i++) {
cin>>a[i];
}
long long ans=0;
sort(a,a+N);
for (int i=0;i<N;i++) {
long long x=lower_bound(a+i+1,a+N,a[i]+P)-a;
long long y=upper_bound(a+i+1,a+N,P-a[i])-a;
ans+=max(0ll,x-y);
}
cout<<ans<<endl;
return 0;
}