[无主题] 三题
1.LGTB 玩扫雷
题意
在一个n m 的棋盘上,有位置上有雷(用“*” 表示),其他位置是空地(用“.” 表示)。
LGTB 想在每个空地上写下它周围8 个方向相邻的格子中有几个雷。
请帮助他输出写了之后的棋盘
输入
输入第一行包含两个整数n, m 代表棋盘大小
接下来n 行,每行m 个字符,代表棋盘
1≤n,m≥1000
输出
输出包含n 行,每行m 个字符,代表LGTB 写了数字之后的棋盘
样例
样例输入
3 3
*.*
...
*.*
样例输出
*2*
242
*2*
提示:暴力
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int zl[2][8]={{1,1,1,0,0,-1,-1,-1},{-1,0,1,-1,1,-1,0,1}}; 5 int a[1005][1005]; 6 int n,m; 7 void sol(int x,int y); 8 bool can(int x,int y); 9 int main() 10 { 11 cin>>n>>m; 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=m;j++) 14 { 15 char w; 16 scanf("%c",&w); 17 while(w!='*'&&w!='.') 18 scanf("%c",&w); 19 if(w=='*') 20 { 21 a[i][j]=-1; 22 sol(i,j); 23 } 24 } 25 for(int i=1;i<=n;i++) 26 { 27 for(int j=1;j<=m;j++) 28 { 29 if(a[i][j]==-1)printf("*"); 30 else printf("%d",a[i][j]); 31 } 32 printf("\n"); 33 } 34 return 0; 35 } 36 bool can(int x,int y) 37 { 38 if(a[x][y]==-1)return false; 39 if(x<1||y<1||x>n||y>m)return false; 40 return true; 41 } 42 void sol(int x,int y) 43 { 44 for(int i=0;i<=7;i++) 45 { 46 int qx=x+zl[0][i]; 47 int qy=y+zl[1][i]; 48 if(can(qx,qy)) 49 a[qx][qy]++; 50 } 51 return ; 52 }
2.LGTB 学分块
题意
LGTB 最近在学分块,但是他太菜了,分的块数量太多他就混乱了,所以只能分成3 块
今天他得到了一个数组,他突然也想把它分块,他想知道,把这个数组分成3 块,块可以为空。假设3 块各
自的和中的最大值最小
请输出分完之后3 块中的最大值
输入
输入第一行包含一个整数n 代表数组大小
接下来n 个整数a1, a2, ..., an,代表数组
对于40% 的数据,1≤n≥10
对于70% 的数据,1≤n≥103
对于100% 的数据,1≤n≥105, 1≤ai≥107
输出
输出包含1 个整数,代表分块完成后3 块中的最大值
样例
样例输入
10
2 5 1 4 7 3 6 2 5 1
样例输出
14
提示:二分
注意:ans=0x3f3f3f3f3f3f3f3fLL; LL很重要!!! 默认是long,不够long long;
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 using namespace std; 7 int n; 8 long long ans=0x3f3f3f3f3f3f3f3fll; 9 int a[100005]; 10 long long sum[100005]; 11 int main() 12 { 13 cin>>n; 14 for(int i=1;i<=n;i++) 15 { 16 sum[i]=sum[i-1]; 17 scanf("%d",&a[i]); 18 sum[i]+=a[i]; 19 } 20 if(n==1) 21 { 22 cout<<a[1]; 23 return 0; 24 } 25 if(n==2) 26 { 27 cout<<max(a[1],a[2]); 28 return 0; 29 } 30 for(int i=1;i<=n;i++) 31 { 32 long long sum_1=sum[i-1]; 33 int l=i+1,r=n+1; 34 while(l+1<r) 35 { 36 int mid=(l+r)>>1; 37 if(sum[mid-1]-sum_1<=sum[n]-sum[mid-1]) 38 l=mid; 39 else r=mid; 40 } 41 long long sum_2=sum[l-1]-sum_1; 42 long long sum_3=sum[n]-sum[l-1]; 43 ans=min(ans,max(sum_1,max(sum_2,sum_3))); 44 sum_2=sum[l]-sum_1; 45 sum_3=sum[n]-sum[l]; 46 ans=min(ans,max(sum_1,max(sum_2,sum_3))); 47 } 48 cout<<ans<<endl; 49 return 0; 50 }
3.LGTB 玩THD
提示:动态规划
易错点:F[i][j] 第 i 个士兵在还能打 j 次取得(包括两种情况:1.塔打死了,没有钱。。。 2.我打死了,有钱!)
初值负无穷,f[0][1]=0;/*因为人比塔先打 人初始有一次*/ ans=-100000;
j 按照题上数组来算;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 struct soldier{ 8 int h,g,ta_time,s_time; 9 }s[105]; 10 int ans=-100000; 11 int P,Q,n; 12 int f[105][1005]; 13 int main() 14 { 15 cin>>P>>Q>>n; 16 for(int i=1;i<=n;i++) 17 { 18 scanf("%d%d",&s[i].h,&s[i].g); 19 s[i].ta_time=(s[i].h-1)/Q; 20 s[i].s_time=(s[i].h-s[i].ta_time*Q-1)/P+1; 21 } 22 for(int i=0;i<=n;i++) 23 for(int j=0;j<=1004;j++) 24 f[i][j]=-1000000000; 25 f[0][1]=0; 26 for(int i=1;i<=n;i++) 27 for(int j=0;j<=1004;j++) 28 { 29 if(f[i][j+s[i].ta_time+1]<f[i-1][j]) 30 f[i][j+s[i].ta_time+1]=f[i-1][j]; 31 if(j>=s[i].s_time-s[i].ta_time) 32 { 33 if(f[i][j-s[i].s_time+s[i].ta_time]<f[i-1][j]+s[i].g) 34 f[i][j-s[i].s_time+s[i].ta_time]=f[i-1][j]+s[i].g; 35 } 36 } 37 for(int j=0;j<=1004;j++) 38 ans=max(ans,f[n][j]); 39 printf("%d\n",ans); 40 return 0; 41 }