女生赛题解
http://10.8.128.203:7217/contest.php?cid=1066
A、B有一定难度;
注意以后在左移右移的时候是否要转换类型,转换成long long
特别是B题有很好的思路,大数无法计算那就转化成log进行计算,特别是对精度要求不高的时候。
题解:
A:思维题
求&之和。统计每个数有多少个0,然后这些0上填1和0都会&后变为0,在n有1的地方如果i为1那么答案就是1;
注意1LL << ans,因为答案可能会爆int,以后注意。
B:思维题
取log,注意精度,1.99999 + 2.00002 如果直接取int的话答案是不对的,维护前缀和。
C:找规律
设三种史莱姆有a、b、c三种,分别有m1、m2、m3只。
首先m1、m3有d只转化为m2。
然后剩下的m1和部分m2转化为m3。
如果此时m2和m3的个数相等,则可以转化成功。
容易推出m3 - m2 = 3 (2d - m1);
可知必须存在两种史莱姆的数量之差是3的整数倍,才可以合并。
D:简单的DP
正向走和反向走是一样的。
dp[i][j][k][v]表示从(1,1)到 (i,j) 和(k,v)两条路取的糖果最大数量。
同时i = k,且j = v的时候只加一个值。保证糖果不会重复取。
但是这道题刚开始的时候我做错了。
我把这个状态表示为从(1,1)到(i,j)和从(n,n)到(k,v)了,这样是不对的,因为在(n,n)到(k,v)这条路上取到的糖果可能会再被取一遍(此时无法判重)
E:签到题
F:打表找规律
通过打表发现,%5每20个数为一个周期,%7每16个数为一个周期。
还是注意要开long long
G:签到题
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; long long T,n,t,ans; void solve(){ scanf("%lld",&T); while(T --){ scanf("%lld",&n); t = n,ans = 0; while(t){ if(!(t & 1)) ans ++; t >>= 1; } if(n == 0) printf("0\n"); else printf("%lld\n",n - (1LL << ans)); } return; } int main(){ solve(); return 0; }
B:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int MAXN = 1e6 + 11; double sum[MAXN]; int T,l,r; void solve(){ for(int i = 1;i <= 1000001;i ++) sum[i] = sum[i - 1] + log10(i); cin >> T; while(T --){ scanf("%d %d",&l,&r); printf("%d\n",(int)(sum[r] - sum[l - 1]) + 1); } return; } int main(){ solve(); return 0; }
C:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int T; int a[5]; void solve(){ cin >> T; while(T --){ scanf("%d%d%d",&a[1],&a[2],&a[3]); sort(a + 1,a + 4); int a1 = (a[3] - a[1]) % 3,a2 = (a[2] - a[1]) % 3,a3 = (a[3] - a[2]) % 3; if(!a1 || !a2 || !a3) printf("YES\n"); else printf("NO\n"); } return; } int main(){ solve(); return 0; }
D:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int MAXN = 13; int dp[MAXN][MAXN][MAXN][MAXN]; int ma[MAXN][MAXN]; int n,T; int Max(int x,int y,int a,int b){ x = max(x,y),a = max(a,b); return max(x,a); } void solve(){ memset(dp,0,sizeof(dp)); cin >> n; for(int i = 1;i <= n;i ++) for(int j = 1;j <= n;j ++) scanf("%d",&ma[i][j]); for(int i = 1;i <= n;i ++){ for(int j = 1;j <= n;j ++){ for(int k = 1;k <= n;k ++){ for(int v = 1;v <= n;v ++){ dp[i][j][k][v] = Max(dp[i - 1][j][k - 1][v],dp[i - 1][j][k][v - 1],dp[i][j - 1][k - 1][v] ,dp[i][j - 1][k][v - 1]) + ma[i][j] + ma[k][v]; if(i == k && j == v) dp[i][j][k][v] -= ma[k][v]; } } } } cout << dp[n][n][n][n] << endl; return; } int main(){ cin >> T; while(T --) solve(); return 0; }

浙公网安备 33010602011771号