第一題大概題面:
思路:,直接計算答案呢不好算,我們考慮先設,然後把多算的面(內部的面)減掉,考慮一個立方體的座標爲,很容易得到與它相鄰的個面的座標,如果這些座標也有立方體,就減去相應的貢獻即可,注意每次的時候需要把一個連通塊內的編號設置爲統一的,防止死循環。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e4+5;
int n,ans;
int x[maxn],y[maxn],z[maxn];
int d[6][3]={{-1,0,0},{1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
int vis[21][21][21];
void dfs(int x,int y,int z,int ct)
{
vis[x][y][z]=ct;
int dx,dy,dz;
for(int i=0;i<6;i++)
{
dx=x+d[i][0];
dy=y+d[i][1];
dz=z+d[i][2];
if(dx<0||dx>20||dy<0||dy>20||dz<0||dz>20||!vis[dx][dy][dz])
continue;
ans--;
if(vis[dx][dy][dz]!=ct)
dfs(dx,dy,dz,ct);
}
}
//給出n塊積木的座標 n<=1e4 0<=x,y,z<=20
//積木爲正方體 邊長爲1
//積木可以懸空
//求這個立體結構的表面積
//10分
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>x[i]>>y[i]>>z[i];
vis[x[i]][y[i]][z[i]]=1;
}
ans=6*n;
int ct=2;
for(int i=0;i<n;i++)
{
if(vis[x[i]][y[i]][z[i]]==1)
dfs(x[i],y[i],z[i],ct++);
}
cout<<ans<<endl;
}
第二題大概題面:
更詳細的題解可以看這一篇:https://blog.csdn.net/xiji333/article/details/104885433
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n;
int a[maxn];
//求矩形的最大面積
//力扣原題 單調棧可解
//20分
int main()
{
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
a[n]=-1;
stack<int> s;
ll ans=0;
for(int i=0;i<=n;i++)
{
if(s.empty()||a[i]>=a[s.top()])
s.push(i);
else
{
int tmp;
while(!s.empty()&&a[i]<a[s.top()])
{
tmp=s.top();
s.pop();
ans=max(ans,(i-tmp)*1ll*a[tmp]);
}
s.push(tmp);
a[tmp]=a[i];
}
}
cout<<ans<<endl;
return 0;
}
第三題大概題面:
思路:爆搜?即便加了剪枝也只能過百分之左右的樣例。顯然不是正解。考慮用表示前位數字的和爲,第位數字爲,第位數字爲時的方案數,那麼對於滿足:的,我們可以得到轉移方程:顯然還需要滿足:。最終答案是什麼呢,顯然就是所有的之和,枚舉即可得到結果。總複雜度,考慮的取值範圍,大概在,實際上應該會更快,因爲加了剪枝。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e6+9;
int n,s,x;
int dp[51][10][10][1000];
//n位數字 可以有前導零
//滿足所有數字加起來的和等於s
//任意三位連續數字構成的三位數可以被x整除
//這樣的數字成爲神奇數字 求神奇數字的個數
int main()
{
cin>>n>>s>>x;
for(int i=0;i<10;i++)
{
for(int j=0;j<10&&i+j<=s;j++)
dp[2][i][j][i+j]=1;
}
for(int i=3;i<=n;i++)
for(int a=0;a<10;a++)
for(int b=0;b<10;b++)
for(int c=0;c<10;c++)
{
if((a*100+b*10+c)%x)
continue;
for(int j=a+b+c;j<=s;j++)
dp[i][b][c][j]=(dp[i][b][c][j]+dp[i-1][a][b][j-c])%mod;
}
int ans=0;
for(int a=0;a<10;a++)
for(int b=0;b<10;b++)
ans=(ans+dp[n][a][b][s])%mod;
cout<<ans<<endl;
return 0;
}
第四題:感覺算個大模擬吧,寫了一半不想寫了溜了。