AtCoder Beginner Contest 196題解
Difference Max
題目大意
輸入四個數\(a,b,c,d\),求\(max([a,b]-[c,d])\)的值,其中\([x,y]\)值\(x\)~\(y\)中的任意數。
題解
因為資料範圍很小,所以我們可以用兩個迴圈來列舉這兩個數,再一一比較,求出答案,時間複雜度為\(O((b-a)\cdot(d-c))\)。
其實,要想使\([a,b]-[c,d]\)最大,只要使被減數最大,減數最小即可,所以答案為\(b-c\),時間複雜度為\(O(1)\)。
程式碼
#include<bits/stdc++.h>//列舉 using namespace std; int main() { int n1,m1,n2,m2,ans=INT_MIN; cin>>n1>>m1>>n2>>m2; for(int i=n1;i<=m1;i++) { for(int j=n2;j<=m2;j++) { ans=max(ans,i-j); } } cout<<ans; return 0; }
#include<bits/stdc++.h>//數學
using namespace std;
int main()
{
int a,b,c,d;
cin>>a>>b>>c>>d;
cout<<b-c;
return 0;
}
Round Down
題目大意
輸入一個實數\(n\),把它的整數部分輸出。
題解
很明顯,任何一個整型變數都無法存下這麼大的一個數,所以我們開一個字串來儲存。
我們是可以不把\(n\)全部讀入的,一旦讀到小數點就退出,否則輸出這個字元。
注意一點,就是如果\(n\)本身是整數怎麼辦?也就是說,讀到換行也要退出。要用scanf才能讀到換行。
程式碼
#include<bits/stdc++.h>
using namespace std;
int main()
{
char ch;
while(1)
{
scanf("%c",&ch);
if(ch=='.')break;
if(ch=='\n')break;
printf("%c",ch);
}
return 0;
}
Doubled
題目大意
輸入一個數\(n\),求從\(1\)$n$中有多少個$k(k%2=0)$位數滿足前$1$\(k/2\)位與\(k/2+1\)~\(k\)位完全一樣。
如:\(123123\),\(2020\)
題解
這道題同樣也不能暴力過,但我們發現一旦確定前\(1\)
我們還有滿足前面的數拼起來小於\(n\),只要把這個數複製一下就可以了。
程式碼
int Log=log10(i)+1;//複製程式碼
long long k=i*pow(10,Log)+i;
#include<bits/stdc++.h>//完整程式碼
using namespace std;
int main()
{
long long n,ans=0;
scanf("%lld",&n);
for(long long i=1;;i++)
{
long long Log=log10(i)+1;
if(i*pow(10,Log)+i<=n)
ans++;
else
break;
}
printf("%d",ans);
return 0;
}
Hanjo
題目大意
在一個\(n\cdot m\)的棋盤上擺\(1\cdot 1\)和\(1\cdot 2\)和\(2\cdot 1\)的磚,把棋盤蓋滿,並且用\(a\)塊\(2\cdot 1\)的磚\(1\cdot 2\)的磚,\(b\)塊\(1\cdot 1\)的磚。
如:
題解
這道題資料很小,所以我們可以用DFS過,暴力搜尋每一個位置放什麼,對於每個位置,分三種情況:
- 放一個\(1\cdot 1\)的磚(不放\(2\cdot 1\)或\(1\cdot 2\)的磚)。
- 放一個\(1\cdot 2\)的磚。
- 放一個\(2\cdot 1\)的磚。
當然,設 \(f_{i,j}\)代表第\(i,j\)的位置上有沒有磚,如果這個位置放磚,就把 \(f_{i,j}=true\),然後回朔。
關於DFS,設三個引數\(x,y,z,x\)代表搜尋在\(x\)行,\(y\)代表搜尋在\(y\)列,\(z\)代表用了\(z\)個\(1\cdot 2\)的磚或\(2\cdot 1\)的磚。
如果\(y=m+1\),即搜尋的列到了邊緣,那麼\(x++,y=1\);,也就是說進入下一行的搜尋。
如果\(z=a\),即\(1\cdot 2\)的磚和\(2\cdot 1\)的磚全用完了,因為題目要求\(2a+b=nm\),所以此時不管搜尋到哪裡,剩下的空位都可以用\(1\cdot 1\)的磚補足,\(ans++;retrurn;\)。
如果\(x=n+1\),即搜尋到邊界,並且當前的解不合法,直接\(return;\)。
如果 \(f_{x,y}=true\),即這個位置已經放好了,那麼直接搜尋下一格\(dfs(x,y+1,z)\)。
如果上面的情況都沒有滿足,那麼直接搜尋。
-
放一個\(1\cdot 2\)的磚:滿足\(f_{x,y+1}=0\)並且\(y+1\le m\),然後\(dfs(x,y+2,z+1)\),注意是\(y+2\),因為這個磚只有\(2\)格寬,記得回朔。
-
放一個\(2\cdot 1\)的磚:滿足\(f_{x+1,y}=0\)並且\(x+1\le n\),然後\(dfs(x,y+1,z+1)\),注意是\(y+1\),因為這個磚只有\(1\)格寬,記得回朔。
-
一個都不放,直接\(dfs(x,y+1,z);\)
程式碼
#include<bits/stdc++.h>
using namespace std;
int n,m,a,b,ans;
bool f[30][30];
void dfs(int x,int y,int z)
{
if(y==m+1)
{
x++;
y=1;
}
if(z==a)
{
ans++;
return;
}
if(x==n+1)
return;
if(f[x][y])
dfs(x,y+1,z);
else
{
if(!f[x][y+1]&&y+1<=m)
{
f[x][y+1]=true;
dfs(x,y+2,z+1);
f[x][y+1]=false;
}
if(!f[x+1][y]&&x+1<=n)
{
f[x+1][y]=true;
dfs(x,y+1,z+1);
f[x+1][y]=false;
}
dfs(x,y+1,z);
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&a,&b);
dfs(1,1,0);
cout<<ans;
return 0;
}