20220806牛客第六场
Lcon Design
题目大意:
给定
请你按照输入的n来将其输出
解:
直接模拟就好了
#include <bits/stdc++.h>
using namespace std ;
int n,xx,yx;
int ma[1000][1000];
void pp() {
for(int i=1;i<=yx;i++) {
for(int j=1;j<=xx;j++) {
if(ma[j][i]==1) cout<<"*";
if(ma[j][i]==2) cout<<".";
if(ma[j][i]==3) cout<<"@";
if(ma[j][i]==0) cout<<".";
}
cout<<endl;
}
cout<<endl;
}
void solve(int x,int y,int i) {
x--;
y--;
for(int j=1;j<=2*n+3;j++) {
for(int k=1;k<=2*n+3;k++) {
if(i==1) {
if(j==k || (j==1 || j==2*n+3) )
ma[j+x][k+y]=3;
else ma[j+x][k+y]=2;
}
if(i==2) {
if(j==1) ma[j+x][k+y]=3;
if(k==1 || k==n+2) ma[j+x][k+y]=3;
}
if(i==3) {
if(j==1) ma[j+x][k+y]=3;
if(k==2*n+3) ma[j+x][y+k]=3;
}
if(i==4) {
if(k==1 || k==n+2 || k==2*n+3)
ma[j+x][y+k]=3;
if(j==1 &&k<=n+2) ma[j+x][y+k]=3;
if(j==2*n+3 && k>=n+3) ma[j+x][y+k] =3;
}
}
}
//pp();
}
void zz(int x,int y) {
x--;
y--;
for(int i=1;i<=n+1;i++) {
for(int j=1;j<=2*n+3;j++) {
ma[x+i][y+j]=2;
}
}
// pp();cout<<endl;
}
int main() {
// int ma[1000][1000];
memset(ma,0,sizeof(ma));
cin>>n;
xx=13*n+19,yx=4*n+5;
for(int i=1;i<=xx;i++) {
ma[i][1]=1;
ma[i][yx]=1;
}
for(int i=1;i<=yx;i++) {
ma[1][i]=1;
ma[xx][i]=1;
}
for(int i=2;i<xx;i++) {
for(int j=2;j<=n+1;j++) {
ma[i][j]=2;
}
for(int j=3*n+5;j<=yx-1;j++) {
ma[i][j]=2;
}
}
zz(2,n+2);
zz(3*n+6,n+2);
zz(6*n+10,n+2);
zz(9*n+14,n+2);
zz(12*n+18,n+2);
// pp();
solve(n+3,n+2,1);
solve(n+3+(3*n+4),n+2,2);
solve(n+3+2*(3*n+4),n+2,3);
solve(n+3+3*(3*n+4),n+2,4);
pp();
return 0;
}Number Game
题目大意:
给定三个数abc,有下面两种操作
1.将b变成a-b
2.将c变成b-c
再给定一个数x,能不能通过上面这两种操作将c变成x
解:
首先b只会有两种值,我们命名为b1=b和b2=a-b
假如先用b1对c去操作,接下来就是b2对c去操作才有意义,否则c不变,接着分操作次数去分析得到公式
然后用b2去对c去操作也是同理
#include <bits/stdc++.h>
using namespace std ;
int n,xx,yx;
int ma[1000][1000];
void pp() {
for(int i=1;i<=yx;i++) {
for(int j=1;j<=xx;j++) {
if(ma[j][i]==1) cout<<"*";
if(ma[j][i]==2) cout<<".";
if(ma[j][i]==3) cout<<"@";
if(ma[j][i]==0) cout<<".";
}
cout<<endl;
}
cout<<endl;
}
void solve(int x,int y,int i) {
x--;
y--;
for(int j=1;j<=2*n+3;j++) {
for(int k=1;k<=2*n+3;k++) {
if(i==1) {
if(j==k || (j==1 || j==2*n+3) )
ma[j+x][k+y]=3;
else ma[j+x][k+y]=2;
}
if(i==2) {
if(j==1) ma[j+x][k+y]=3;
if(k==1 || k==n+2) ma[j+x][k+y]=3;
}
if(i==3) {
if(j==1) ma[j+x][k+y]=3;
if(k==2*n+3) ma[j+x][y+k]=3;
}
if(i==4) {
if(k==1 || k==n+2 || k==2*n+3)
ma[j+x][y+k]=3;
if(j==1 &&k<=n+2) ma[j+x][y+k]=3;
if(j==2*n+3 && k>=n+3) ma[j+x][y+k] =3;
}
}
}
//pp();
}
void zz(int x,int y) {
x--;
y--;
for(int i=1;i<=n+1;i++) {
for(int j=1;j<=2*n+3;j++) {
ma[x+i][y+j]=2;
}
}
// pp();cout<<endl;
}
int main() {
// int ma[1000][1000];
memset(ma,0,sizeof(ma));
cin>>n;
xx=13*n+19,yx=4*n+5;
for(int i=1;i<=xx;i++) {
ma[i][1]=1;
ma[i][yx]=1;
}
for(int i=1;i<=yx;i++) {
ma[1][i]=1;
ma[xx][i]=1;
}
for(int i=2;i<xx;i++) {
for(int j=2;j<=n+1;j++) {
ma[i][j]=2;
}
for(int j=3*n+5;j<=yx-1;j++) {
ma[i][j]=2;
}
}
zz(2,n+2);
zz(3*n+6,n+2);
zz(6*n+10,n+2);
zz(9*n+14,n+2);
zz(12*n+18,n+2);
// pp();
solve(n+3,n+2,1);
solve(n+3+(3*n+4),n+2,2);
solve(n+3+2*(3*n+4),n+2,3);
solve(n+3+3*(3*n+4),n+2,4);
pp();
return 0;
}M.Z-game on grid
题目大意:
两个人在NbM.com的网格上轮流移动一个棋子。棋子初始位置为(1,1)。每次只能向右或者向上移动一格。每个网格上面都有一些标记,移到‘A’的点爱丽丝赢,移到‘B’的点爱丽丝输,没有移到特殊点并且不能再移动则为平局。
给出先手是否必胜,必平,必败
解:
考虑dp
对三种情况分三次进行求解,按照每种情况dp设值不同
拿是否能赢的情况举例,如果(n-1,m-1)的值为“A”,那么这个位置的dp值就是1,否则就是0
从右上往左下开始递推,当前来到了(i,j)位置
如果当前位置为“A”,那么这个位置dp值就是1,爱丽丝就赢了,如果当前位置是“B”,这个位置dp值就是0,因为在这个点爱丽丝是输得。
当前位置如果为“.”,那么就要分情况讨论,如果爱丽丝先手并且在(i+1,j)或者(i,j+1)位置有dp为1的值爱丽丝就可以走到那一步上去从而取得胜利。如果爱丽丝后手,那么就要保证(i+1,j)和(i,j+1)位置上dp值都为1,因为此时不论对手走哪一条路爱丽丝都能走到dp值为1的地方从而取得胜利。
对于其他的情况都是一样的分析这里就不赘述。
代码以及思想均来自fn学长
#include<bits/stdc++.h>
#define ll long long
#define cer(x) cerr<<(#x)<<" = "<<(x)<<'\n'
#define endl '\n'
using namespace std;
const int N=505;
ll n,m;
string s[N];
int f[4][N][N]; // f[1][i][j]表示考虑i,j右下角时的答案1
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t; cin>>t;
while(t--){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>s[i];
}
for(int i=1;i<=3;i++){
for(int j=0;j<=n;j++){
for(int k=0;k<=m;k++){
f[i][j][k]=0; // 初始化
}
}
}
if(s[n-1][m-1]=='A'){
f[1][n-1][m-1]=1; // 可以赢
}
else if(s[n-1][m-1]=='.'){
f[2][n-1][m-1]=1; // 可以平局
}
else{ // 'B'
f[3][n-1][m-1]=1; // 可以输
}
// 转移f[1][j][k],是否能赢
for(int j=n-1;j>=0;j--){
for(int k=m-1;k>=0;k--){
if(j==n-1 && k==m-1)continue;
if(s[j][k]=='A'){
f[1][j][k]=1;
}
else if(s[j][k]=='B'){
f[1][j][k]=0;
}
else{ // '.'
if((j+k)%2==0){ // 轮到Alice走
if(j+1<=n-1)f[1][j][k]=max(f[1][j][k],f[1][j+1][k]);
if(k+1<=m-1)f[1][j][k]=max(f[1][j][k],f[1][j][k+1]);
}
else{ // 轮到Bob走
f[1][j][k]=1;
if(j+1<=n-1)f[1][j][k]=min(f[1][j][k],f[1][j+1][k]);
if(k+1<=m-1)f[1][j][k]=min(f[1][j][k],f[1][j][k+1]);
}
}
}
}
// 转移f[3][j][k],是否能输
for(int j=n-1;j>=0;j--){
for(int k=m-1;k>=0;k--){
if(j==n-1 && k==m-1)continue;
if(s[j][k]=='A'){
f[3][j][k]=0;
}
else if(s[j][k]=='B'){
f[3][j][k]=1;
}
else{ // '.'
if((j+k)%2==0){ // 轮到Alice走
if(j+1<=n-1)f[3][j][k]=max(f[3][j][k],f[3][j+1][k]);
if(k+1<=m-1)f[3][j][k]=max(f[3][j][k],f[3][j][k+1]);
}
else{ // 轮到Bob走
f[3][j][k]=1;
if(j+1<=n-1)f[3][j][k]=min(f[3][j][k],f[3][j+1][k]);
if(k+1<=m-1)f[3][j][k]=min(f[3][j][k],f[3][j][k+1]);
}
}
}
}
// 转移f[2][j][k],是否能平局
for(int j=n-1;j>=0;j--){
for(int k=m-1;k>=0;k--){
if(j==n-1 && k==m-1)continue;
if(s[j][k]=='A'){
f[2][j][k]=0;
}
else if(s[j][k]=='B'){
f[2][j][k]=0;
}
else{ // '.'
if((j+k)%2==0){ // 轮到Alice走
if(j+1<=n-1)f[2][j][k]=max(f[2][j][k],f[2][j+1][k]);
if(k+1<=m-1)f[2][j][k]=max(f[2][j][k],f[2][j][k+1]);
}
else{ // 轮到Bob走
f[2][j][k]=1;
if(j+1<=n-1)f[2][j][k]=min(f[2][j][k],f[2][j+1][k]);
if(k+1<=m-1)f[2][j][k]=min(f[2][j][k],f[2][j][k+1]);
}
}
}
}
if(f[1][0][0])cout<<"yes "; // 可以赢
else cout<<"no ";
if(f[2][0][0])cout<<"yes "; // 可以平局
else cout<<"no ";
if(f[3][0][0])cout<<"yes"<<endl; // 可以输
else cout<<"no"<<endl;
}
return 0;
}
#ACM##菜鸡的求救#