纸钱晚风送,谁家又添新痛。
AtCoder Beginner Contest 184
A
B
两个签到
1 2 3 4 5 6 7 8 9 10 11 12 #include <bits/stdc++.h> using namespace std;using ll=long long ;const int N=1e6 +100 ;int a[N];int main () { int a,b,c,d; cin>>a>>b>>c>>d; cout<<a*d-b*c; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <bits/stdc++.h> using namespace std;using ll=long long ;const int N=1e6 +100 ;int a[N];int main () { ll n,x; string s; cin>>n>>x; cin>>s; for (int i=0 ;i<=s.length ()-1 ;i++) { if (s[i]=='o' ){ x++; } else { if (x>0 ) x--; } } cout<<x; return 0 ; }
C
总共可以走一步,二步,三步,我觉得三步之后一定能够走完,因此可以直接进行判断
如果是0就是重合
如果是1就是题意得情况进行模拟
如果是2,它可以是斜着走加短距离,斜着走加斜着走,短距离加短距离,赛时短距离加短距离忘想了,但还是冲过去了。
剩下的三步即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #include <bits/stdc++.h> using namespace std;#define rep(i, a, n) for (int i = a; i <= n; i++) #define frep(i, a, n) for (int i = a; i >= ni--) const int N = 1e5 + 100 ;int main () {int a,b,c,d;cin>>a>>b>>c>>d; if (a==c&&b==d){ cout<<0 ; return 0 ; } if (a+b==c+d||a-b==c-d||abs (a-c)+abs (b-d)<=3 ){ cout<<1 ; return 0 ; } if (((d-c)&1 )==((b-a)&1 )){ cout<<2 ; return 0 ; } if (abs (c+d-a-b)<=3 ){ cout<<2 ; return 0 ; } if (abs (abs (a-b)-abs (c-d))<=3 ){ cout<<2 ; return 0 ; } if (abs (a-c)+abs (b-d)<=6 ){ cout<<2 ; return 0 ; } cout<<3 ; return 0 ;}
D
期望dp,直接定义dp[a][b][c]
为到结果得步数,然后逆推走期望dp即可。
非常典型得期望dp,直接从结果推回来即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <bits/stdc++.h> using namespace std;double dp[110 ][110 ][110 ];int a,b,c;int main () {cin>>a>>b>>c; dp[100 ][100 ][100 ]=0 ; for (int i=99 ;i>=a;i--){ for (int j=99 ;j>=b;j--) { for (int k=99 ;k>=c;k--) { dp[i][j][k]+=((dp[i+1 ][j][k]+1.0 )*(i*1.0 )+(dp[i][j+1 ][k]+1.0 )*j*1.0 +(dp[i][j][k+1 ]+1.0 )*k*1.0 )/(i+j+k); } } } printf ("%.9lf" ,dp[a][b][c]);return 0 ;}
E
考验基本功的bfs,主要就是有一个点,就是一个字母之前跳过了以后就没必要跳了,这样其实复杂度和普通的bfs是没有太大去别的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 #include <bits/stdc++.h> using namespace std;const int N=2001 ;char a[N][N];bool vis[N][N];int dx[4 ]={0 ,0 ,1 ,-1 };int dy[4 ]={1 ,-1 ,0 ,0 };queue<pair<int ,int > >q; vector<pair<int ,int > >p[50 ]; int dp[2020 ][2020 ];int vvis[N];int main () {int h,w;cin>>h>>w; int mx,my;for (int i=1 ;i<=h;i++){ for (int j=1 ;j<=w;j++) { cin>>a[i][j]; if (a[i][j]=='S' ) { q.push ({i,j}); vis[i][j]=1 ; } if (a[i][j]>='a' &&a[i][j]<='z' ) { p[a[i][j]-'a' ].push_back ({i,j}); } if (a[i][j]=='G' ) { mx=i; my=j; } } } while (!q.empty ()){ pair<int ,int >c=q.front (); q.pop (); int x=c.first;int y=c.second;if (dp[mx][my]){ break ; } for (int i=0 ;i<4 ;i++){ int tx=x+dx[i];int ty=y+dy[i];if (a[tx][ty]=='#' ||vis[tx][ty]||tx<1 ||ty<1 ||tx>h||ty>w){ continue ;} q.push ({tx,ty}); vis[tx][ty]=1 ; dp[tx][ty]=dp[x][y]+1 ; } if (a[x][y]>='a' &&a[x][y]<='z' ){ char cc=a[x][y]; if (vvis[cc-'a' ]) { continue ; } vvis[cc-'a' ]=1 ; for (int i=0 ;i<p[cc-'a' ].size ();i++) { int tx=p[cc-'a' ][i].first; int ty=p[cc-'a' ][i].second; if (vis[tx][ty]) { continue ; } vis[tx][ty]=1 ; q.push ({tx,ty}); dp[tx][ty]=dp[x][y]+1 ; } } } if (dp[mx][my]==0 ){ cout<<-1 ; return 0 ; } cout<<dp[mx][my]; return 0 ;}
F
由于N<=40,直接进行折半,然后直接进行状压,枚举出一部分,再用二分去弄另一部分
本题学会了状压来枚举所有状态值得纪念。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <bits/stdc++.h> using namespace std;const int N=45 ;using ll=long long ;ll t,a[N],b[N],c[N]; ll ans; ll d[2200000 ]; int cnt;int main () { int n; cin>>n>>t; for (int i=1 ;i<=n;i++){ cin>>a[i]; } int x=n/2 ;int y=n-n/2 ;for (int i=1 ;i<=x;i++){ b[i]=a[i]; } for (int i=1 ;i<=y;i++){ c[i]=a[n-i+1 ]; } for (int i=0 ;i<=(1 <<x)-1 ;i++){ cnt++; for (int j=1 ;j<=x;j++){ if ((1 <<(j-1 ))&i) { d[cnt]+=b[j]; } } } sort (d+1 ,d+1 +cnt);for (int i=0 ;i<=(1 <<y)-1 ;i++){ ll now=0 ; for (int j=1 ;j<=y;j++) { if (1 <<(j-1 )&i){ now+=c[j]; } } if (now>t) { continue ; } int pos=upper_bound (d+1 ,d+1 +cnt,t-now)-d; pos--; ans=max (ans,now+d[pos]); } cout<<ans; return 0 ;}