Fxx and game


2016年10月29日,bc第89场;做完第二题就不会写额了,只能取干些其他事了。。。。。。。。

Fxx and game

问题描述
青年理论计算机科学家Fxx给的学生设计了一款数字游戏。

一开始你将会得到一个数\:XX,每次游戏将给定两个参数\:k,tk,t, 任意时刻你可以对你的数执行下面两个步骤之一:

1.\:X = X - i(1 <= i <= t)1.X=Xi(1<=i<=t)2.\:2.\:X\:X\:k\:k的倍数,X = X / kX=X/k。

现在Fxx想要你告诉他最少的运行步骤,使\:X\:X变成\:11
输入描述
第一行一个整数\:T(1\leq T\leq20)\:T(1T20)表示数据组数。

接下来\:T\:T行,每行三个数\:X,k,t(0\leq t\leq10^6,1\leq X,k\leq10^6)X,k,t(0t106,1X,k106)

数据保证有解。
输出描述
输出共\:T\:T行。

每行一个整数表示答案。
输入样例
2
9 2 1
11 3 3
输出样例
4
3


题意:一个数n可以进行两种变换,减去从1到t的数的其中一个,或者如果这个数能够整除k,则整除k,求从n到1的最少变换的次数;

思路:可以逆向来考虑一下,就想到于从1到n的最少的次数,然后变换的就是两种:加上从1到t的整数或者乘以k;这个就相当于刚开始写的strang left这个电梯的bfs进行操作;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1000000 + 10;
bool vis[maxn];
ll n,k,t;
struct Node
{
    ll data;
    ll times;
};
ll  bfs()
{
    queue<Node>q;
    Node x;
    x.data = 1;
    x.times = 0;
    q.push(x);
    vis[1] = true;
    while( ! q.empty())
    {
        Node temp = q.front();
        q.pop();
        for(ll i = 1; i <= t ; i ++)
        {
            Node temps;
            temps.data = temp.data + i;
            temps.times = temp.times + 1;
            if(temps.data >= 1 && temps.data <= n && !vis[temps.data])
            {
                if(temps.data == n)
                    return temps.times;
                q.push(temps);
                vis[temps.data] = true;
            }
        }
        Node ts;
        ts.data = temp.data * k;
        ts.times = temp.times + 1;
        if(ts.data >= 1 && ts.data <= n && !vis[ts.data])
        {
            if(ts.data == n)
                return ts.times;
            q.push(ts);
            vis[ts.data] = true;
        }
    }
}
int main()
{
    ll Tcase;
    scanf("%I64d",&Tcase);
    while(Tcase --)
    {
        scanf("%I64d%I64d%I64d",&n,&k,&t);
        memset(vis,false,sizeof(vis));
        printf("%I64d\n",bfs());
    }
    return 0;
}

这里附上第一题的代码吧;

Fxx and string

问题描述
青年理论计算机科学家Fxx得到了一个只包含小写字母的字符串。

字符串的长度为\:nn,下标从1开始,第\:i\:i位的字母为\:s_isi,现在Fxx想知道有多少三元组\:(i,j,k)\:(i,j,k)满足下列条件

1、i,j,k\:i,j,k三个数成等比数列

2、s_i=si='yy',s_j=,sj='rr',s_k=,sk='xx'

3.i/ji/jk/jk/j中必须有整数
输入描述
第一行一个整数\:T(1\leq T\leq100)\:T(1T100)表示数据组数。

接下来\:T\:T行,每行一个仅包含小写字母的字符串(字符串长度不超过\:1000010000
输出描述
输出共\:T\:T行。

每行一个整数表示答案。
输入样例
2
xyyrxx
yyrrxxxxx
输出样例
0
2
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10000 + 10;
char s[maxn];
int main()
{
    int n;
    int Tcase;
    scanf("%d",&Tcase);
    while(Tcase --)
    {
        scanf("%s",s + 1);
        n = strlen(s + 1);
        int ans = 0;
        for(int i = 1;i <= n / 2;i ++)//i代表的是y
        {
            if(s[i] == 'x' || s[i] == 'y')
            for(int j = 2; j * j * i <= n ; j ++)
            {
                if((s[i] == 'y' && s[i * j] == 'r' && s[i * j * j] == 'x')||(s[i] == 'x' && s[i * j] == 'r' && s[i * j * j] == 'y')
                   )
                    ans ++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值