女生赛题解

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;
}
posted @ 2019-12-19 17:53  cgold  阅读(89)  评论(0)    收藏  举报