2017百度之星作死记

资格赛

度度熊与邪恶大魔王

突破口在于防御值,生命值都很低,所以不必拘泥于n
可以预处理出对于防御值i,生命值j的怪兽的最小花费,做一个完全背包
然后对每个询问直接输出

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,can;
int a[100005],b[100005];
int c[1005],p[1005],f[15][1005];
long long ans;
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF) 
    {
        ans=0;can=1;
        for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
        for(int i=1;i<=m;i++) scanf("%d%d",&c[i],&p[i]);
        for(int i=0;i<=10;i++) 
        for(int j=1;j<=1000;j++) f[i][j]=1e9;
        for(int i=1;i<=m;i++) 
        {
            for(int j=0;j<=10;j++)  //枚举防御
            for(int k=1;k<=1000;k++) //生命值 
            if(p[i]-j>0) f[j][k]=min(f[j][k],f[j][max(0,k-(p[i]-j))]+c[i]);
        }
        for(int i=1;i<=n;i++) 
        if(f[b[i]][a[i]]==1e9) can=0; else ans=ans+f[b[i]][a[i]];
        if(can) printf("%I64d\n",ans); else printf("-1\n");
    }
    return 0;
}

初赛A

今夕何夕

码农题,想明白就行

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int cas;
char a[20];
int b[20],p[20];
int year,month,day,s,id,lwq,now;
int run(int x)
{
    if(x%100==0) 
    {
        if(x%400==0) return 1; else return 0;
    }
    if(x%4==0) return 1; else return 0;
}
int main()
{
    b[1]=31;b[2]=28;b[3]=31;
    b[4]=30;b[5]=31;b[6]=30;
    b[7]=31;b[8]=31;b[9]=30;
    b[10]=31;b[11]=30;b[12]=31;
    for(int i=1;i<=12;i++) p[i]=p[i-1]+b[i];
    cin>>cas;
    while(cas--) 
    {
        scanf("%s",a+1);
        year=(a[1]-48)*1000+(a[2]-48)*100+(a[3]-48)*10+a[4]-48;
        month=(a[6]-48)*10+(a[7]-48);
        day=(a[9]-48)*10+(a[10]-48);
        if(month==2&&day==29) lwq=1; else lwq=0;
        s=0;
        now=365+run(year);
        if(month>2) id=p[month-1]+run(year); else id=p[month-1];
        id=id+day; //是每年的第几天 
        s=(s+now-id)%7;
        while(1) 
        {
            year++;
            now=365+run(year);
            if(month>2) id=p[month-1]+run(year); else id=p[month-1];
            if(lwq==1) id=id+28+run(year); else id=id+day;
            s=(s+id)%7;
            if(s==0) 
            {
                if(lwq==1) 
                {
                    if(run(year)==1) break;
                }
                else break;
            }
            s=(s+now-id)%7;
        }
        printf("%d\n",year);
    }        
    return 0;
}

度度熊的01世界

先找1联通块,如果1联通块只有1个,那么0的联通块只要不碰到边界就肯定被1完全包围,dfs即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,s,zero,ans;
char a[105][105];
int p[105][105];
void dfs(int x,int y)
{
    p[x][y]=1;
    if(x+1<=n&&p[x+1][y]==0&&a[x+1][y]=='1') dfs(x+1,y);
    if(x-1>0&&p[x-1][y]==0&&a[x-1][y]=='1') dfs(x-1,y);
    if(y+1<=m&&p[x][y+1]==0&&a[x][y+1]=='1') dfs(x,y+1);
    if(y-1>0&&p[x][y-1]==0&&a[x][y-1]=='1') dfs(x,y-1);
}
int lwq(int x,int y)
{
    int ty=0;
    p[x][y]=1;
    if(x==1||x==n||y==1||y==m) ty=1;
    if(x+1<=n&&p[x+1][y]==0&&a[x+1][y]=='0') ty=ty|lwq(x+1,y);
    if(x-1>0&&p[x-1][y]==0&&a[x-1][y]=='0') ty=ty|lwq(x-1,y);
    if(y+1<=m&&p[x][y+1]==0&&a[x][y+1]=='0') ty=ty|lwq(x,y+1);
    if(y-1>0&&p[x][y-1]==0&&a[x][y-1]=='0') ty=ty|lwq(x,y-1);
    return ty;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF) 
    {
        s=zero=0;
        ans=-1;
        for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
        for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++) p[i][j]=0;
        for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++) 
        if(p[i][j]==0&&a[i][j]=='1') 
        {
            s++;
            if(s>1) ans=-1;
            dfs(i,j);
        }
        for(int i=1;i<=n;i++) 
        for(int j=1;j<=m;j++) 
        if(p[i][j]==0&&a[i][j]=='0') 
        {
            if(lwq(i,j)==0) zero++;
            if(zero>1) ans=-1;
        }
        if(s==1&&zero==1) ans=0;
        if(s==1&&zero==0) ans=1;
        printf("%d\n",ans);
    }
    return 0;
}

初赛B

Chess
组合数

#include<cstdio>
#include<iostream>
using namespace std;
const int mod=1e9+7;
int n,m,t;
int f[1005][1005];  
int main()
{
    for(int i=1;i<=1000;i++) f[i][0]=1;
    f[1][1]=1;
    for(int i=2;i<=1000;i++) 
    for(int j=1;j<=i;j++) f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;
    cin>>t;
    while(t--) 
    {
        scanf("%d%d",&n,&m);
        if(n<m) swap(n,m);
        printf("%d\n",f[n][m]);
    }
    return 0;
}

小小粉丝度度熊

先合并区间,然后二分答案,有许多情况需要判断,十分难写。

#include<cstdio>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
int n,m,len,now;
ll far;
struct ty
{
    ll l,r;
}a[100005];
ll b[100005],c[100005],s[100005];
bool cmp(ty x,ty y)
{
    if(x.l!=y.l) return x.l<y.l;
    return x.r<y.r;
}
int erfen(ll l,ll r)
{
    if(l>r) return l;
    ll mid=(l+r)/2,can=0,cost,id;
    for(int i=1;i<=len;i++) 
    {
        int L=i,R=len,Mid;
        while(L<=R) 
        {
            Mid=(L+R)/2;
            if(c[Mid]-b[i]+1<mid) L=Mid+1; else R=Mid-1;
        }
        id=L;
        if(id==len+1) 
        {
            cost=s[len]-s[i]+(mid-(c[len]-b[i]))-1;
            if(cost<=m) can=1;
        }
        else 
        {
            if(c[id]-b[i]+1>mid) 
            {
                if(b[id]-b[i]<=mid) cost=s[id]-s[i]; else cost=s[id-1]-s[i]+(mid-(c[id-1]-b[i]))-1;
                if(cost<=m) can=1;
            }
            if(c[id]-b[i]+1==mid) 
            {
                 if(s[id]-s[i]<=m) can=1;
            }
        }
    }
    if(can==1) return erfen(mid+1,r); else return erfen(l,mid-1);
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF) 
    {
        len=0; 
        for(int i=1;i<=n;i++) scanf("%I64d%I64d",&a[i].l,&a[i].r);
        sort(a+1,a+n+1,cmp);
        far=a[1].r;now=1;
        for(int i=2;i<=n;i++) 
        if(a[i].l<=far) far=max(far,a[i].r);
        else 
        {
            len++;
            b[len]=a[now].l;
            c[len]=far;
            now=i;
            far=a[i].r;
        }
        len++;
        b[len]=a[now].l;
        c[len]=far;
        for(int i=2;i<=len;i++) s[i]=s[i-1]+(b[i]-c[i-1])-1;
        printf("%I64d\n",erfen(1,2000000000)-1);
    }
    return 0;
}

后记

本来以为复赛肯定是进不了了,结果主办方说初赛A评测情况不好,所以为了补偿,取每场前800,于是又进了复赛。。。
复赛只会第一道模拟,卒。

### 百度2012复赛:蛛网问题的题目与解法 关于百度2012复赛中的“蛛网”问题,虽然具体的题目描述和官方解答可能并未公开详细内容,但可以通过对类似竞赛题目的分析来推测其可能的题目形式和解法。 #### 题目概述 根据过往竞赛的经验,“蛛网”问题通常涉及图论或网格结构相关的算法设计。假设该题目要求在一张二维网格中寻找特定路径或计算某些属性,例如最短路径、连通性或最大流等。以下是对可能题目的推测: - 给定一个 \( n \times m \) 的网格,每个格子可能包含障碍物或具有不同的权重。 - 要求从起点到终点找到一条路径,使得路径满足某种条件(如路径长度最短、权重最小等)。 - 可能需要考虑动态规划、广度优先搜索(BFS)、深度优先搜索(DFS)或最短路径算法(如Dijkstra算法或Floyd-Warshall算法)。 #### 解法分析 针对上述推测的题目类型,以下是几种可能的解法: 1. **广度优先搜索(BFS)** 如果题目要求的是最短路径且权重均为1,则可以使用BFS进行求解。通过维护一个队列,逐步扩展当前节点的所有邻居节点,并记录访问状态和距离信息。 ```python from collections import deque def bfs(grid, start, end): n, m = len(grid), len(grid[0]) queue = deque([start]) visited = [[False] * m for _ in range(n)] visited[start[0]][start[1]] = True distance = [[float('inf')] * m for _ in range(n)] distance[start[0]][start[1]] = 0 directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] while queue: x, y = queue.popleft() if (x, y) == end: return distance[x][y] for dx, dy in directions: nx, ny = x + dx, y + dy if 0 <= nx < n and 0 <= ny < m and not visited[nx][ny] and grid[nx][ny] != '#': visited[nx][ny] = True distance[nx][ny] = distance[x][y] + 1 queue.append((nx, ny)) return -1 ``` 2. **Dijkstra算法** 如果路径中的边有权重,则可以使用Dijkstra算法求解最短路径。通过优先队列维护当前最小距离的节点,并逐步更新相邻节点的距离。 ```python import heapq def dijkstra(grid, start, end): n, m = len(grid), len(grid[0]) distance = [[float('inf')] * m for _ in range(n)] distance[start[0]][start[1]] = 0 pq = [(0, start)] directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] while pq: dist, (x, y) = heapq.heappop(pq) if (x, y) == end: return dist for dx, dy in directions: nx, ny = x + dx, y + dy if 0 <= nx < n and 0 <= ny < m and grid[nx][ny] != '#': new_dist = dist + int(grid[nx][ny]) if grid[nx][ny].isdigit() else dist + 1 if new_dist < distance[nx][ny]: distance[nx][ny] = new_dist heapq.heappush(pq, (new_dist, (nx, ny))) return -1 ``` 3. **动态规划(DP)** 如果题目涉及路径上的累加值或某种全局最优解,可以使用动态规划方法。定义状态 \( dp[i][j] \) 表示到达位置 \( (i, j) \) 的最优解,通过递推公式逐步更新状态。 ```python def dynamic_programming(grid): n, m = len(grid), len(grid[0]) dp = [[float('inf')] * m for _ in range(n)] dp[0][0] = int(grid[0][0]) for i in range(n): for j in range(m): if i > 0: dp[i][j] = min(dp[i][j], dp[i-1][j] + int(grid[i][j])) if j > 0: dp[i][j] = min(dp[i][j], dp[i][j-1] + int(grid[i][j])) return dp[-1][-1] ``` #### 注意事项 - 在实际竞赛中,题目可能包含多种限制条件(如时间复杂度、空间复杂度),需要根据具体要求选择合适的算法[^1]。 - 对于大规模数据,优化算法的时间复杂度和空间复杂度至关重要。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值