2015上海区域赛铜牌题

HDU - 5578

题意:

给出一个字符串,问你相邻最接近的俩个相同字母的间距

题解:

遍历一遍即可

#include <bits/stdc++.h>
using namespace std;
#define ll long long 
string s;
map<char ,int > mp;
int main()
{
    int t;
    cin>>t;
    for(int cas = 1;cas <= t;cas++)
    {
        cin>>s;
        mp.clear();
        int l = s.length(),ans = 100005;
        for(int i=0;i<l;i++){
            if(mp[s[i]] == 0){
                mp[s[i]] = i;
            }
            else{
                ans = min(ans , i - mp[s[i]]);
                mp[s[i]] = i;
            }
        }
        printf("Case #%d: ",cas);
        if(ans == 100005){
            printf("-1\n");
            continue ;
        }
        printf("%d\n",ans);
    }
    return 0;
}

HDU - 5584

题意:

在一个正二维平面上,点(x,y)可以走到(x , y + lcm(x,y))或者(x + lcm(x,y) , y)

现给出一个终止点(xx,yy),问你起点有多少个?

题解:

我们可以发现当前位置是(x,y)时,如果x>y,那么当前位置一定是由(x1,y)走到的,如果x<y,当前位置一定是由(x,y1)走到的,由这点确定了路径的唯一性。

设gcd(x,y)=k,x=nk,y=mk,lcm(x,y)=nmk,那么下一步能走到(n(m+1)k,mk)或者(nk,m(n+1)k),并且由于n(m+1)与m互质,n与m(n+1)互质,所以下一步的gcd依然是k。

根据以上两点,就可以用逆推找出答案,每次都假设x>y,x=nk,y=mk,当前点就是由(x/(y/k+1),y)走到的,如果x不再是(y+k)的倍数(即:(y/k+1)*k的倍数),则表示不能再逆推。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    int t;
    ll n,m;
    cin>>t;
    for(int cas = 1;cas <= t; cas++)
    {
        int ans = 1;
        scanf("%lld%lld",&n,&m);
        ll gc = __gcd(n,m);
        if(n < m)
            swap(n,m);
        while( n%(m + gc) == 0 ){
            ans++;
            n = n/(m/gc + 1);
            if(n < m)
                swap(n,m);
        }
        printf("Case #%d: %d\n",cas,ans);
    }

    return 0;
}

HDU - 5573

题解:

构造题,有一颗满二叉树,编号1 ~ n,现在你要从根节点往下走,初始手里的值 V 为 0,每路过一个节点,可以选择 V 加上或者减去节点的编号值。问你走 k 层,值 V 能否达到 n。(题目保证可以达到)最后输出路径,怎么走的。

1 <= n <= 1e9,n <= 2^k

题解:

题目给出的数据范围非常巧妙,我们可以通过二进制,利用树的最左边的俩条路构造出来任意1-n的答案,我们只需要找到需要减少的值,然后二进制输出即可

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    int t;
    cin>>t;
    for(int cas = 1;cas <= t;cas++)
    {
        ll n,k,ans = 0;
        int flag = 0;
        cin>>n>>k;
        printf("Case #%d: \n",cas);
        ll cnt = ( 1<<(k) ) - 1 - n;
        if(cnt&1)
            cnt++;
        cnt /= 2;
        for(int i=1;i<k;i++){
            flag = cnt%2,cnt /= 2;
            printf("%lld " ,(1ll*1<<(i-1)));
            if(flag){
                printf("-\n");
                ans -= (1<<(i-1));
            }else{
                printf("+\n");
                ans += (1<<(i-1));
            }
        }
        printf("%lld +\n",n - ans);
    }
    return 0;
}
全部评论

相关推荐

陆续:不可思议 竟然没那就话 那就我来吧 :你是我在牛客见到的最美的女孩
点赞 评论 收藏
分享
_mos_:我以为手抄报简历就已经很顶了,没想到还有表格简历
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务