CF #762 Div.3(A ~ E)

CF #762 Div.3

A Square String?(翻译)

Description:

A string is called square if it is some string written twice in a row.

如果一个字符串是某个连续写了两次的字符串,则称为square

​ 给定字符串 判断字符串是否是square

Method:

​ 一开始没有读懂题目 也没有仔细看样例 所以草率地认为是含有奇数个字符时 NO

​ 其实就是扫一遍判断是否是由两个相同字符串构成

Code:

void solve()
{
    cin >> s;
    int n = s.size();
    bool flag = true;
    if(n & 1)   flag = false;
    else
    {
        for(int i = 0; i < n / 2; i++)
            if(s[i] != s[i + n / 2])    flag = false;
    }
    if(flag)    puts("YES");
    else puts("NO");
}

B Squares and Cubes(翻译 + 枚举)

Description:

Polycarp likes squares and cubes of positive integers

Polycarp喜欢正整数的平方和立方

​ 输出小于n的不重复的立方数和平方数的个数

Method:

在计算时间复杂度后直接暴力枚举 最坏情况下取20 * 1e9 O(20 * 1e4) 用map来记录是否重复

Code:

void solve()
{
    int n;
    cin >> n;
    map<int, bool> vis;
    int res = 1;
    for(int i = 2; i * i <= n; i++)
        if(vis[i * i] == false) res ++, vis[i * i] = true;
    for(int i = 2; i * i * i <= n; i++)
        if(vis[i * i * i] == false) res ++, vis[i * i * i] = true;
    cout << res << endl;
}

C Wrong Addition(枚举 + 题意)

Description:

​ 给出两个数 a 和 s 题目定义了一种新的加法 设b 使 a + b = s

​ 若b存在 输出b 若b不存在 输出-1

Method:

​ 按题目模拟 我原有的思路是使用字符串 但是其实LL可以使用%提取最后一位 /消去一位更加方便

​ 1 保证每次减法中得到的数必须是<=10的

​ 2 当s已经走完了 但是a还没走完 不符合题意

​ 3 借位时遇到了0 借不到

Code:

void solve()
{
    LL a, s;
    cin >> a >> s;
    vector<int> b;
    while(s)
    {
        int x = a % 10;
        int y = s % 10;
        if(y - x >= 0)  b.push_back(y - x);
        else 
        {
            s /= 10;
            y += 10 * (s % 10);
            if(y >= 10 && y - x <= 10)  b.push_back(y - x);//如果下一位是0 借位失败
            else 
            {
                cout << -1 << endl;
                return ;
            }
        }
        a /= 10;
        s /= 10;
    }

    if(a)   cout << -1 << endl;
    else 
    {
        while(b.back() == 0)    b.pop_back();
        for(int i = (int)b.size() - 1; i >= 0; i --)    cout << b[i];
        cout << endl;
    }
}

D New Year’s Problem(二分 || 贪心)

Description:

​ 给出n行m列的矩阵 要求从每一列中选择一个

​ 最多在m-1行里选 求所有被选择的物品的最小值的最大值

Method:

总结:因为没有读清楚题目 题意提炼得不够精确 然后又因为题目给的m n换位了 想了很久

​ 当我们看到最小值最大的时候 毫无疑问这道题有二分解法

​ 我们可以枚举整个矩阵 每一行中寻找比mid大的 标记为true

​ 每一列选多了没关系 因为后面可以通过二分来将mid扩大

​ 枚举后 若是有一列 没有true 那就意味着没有该列中不存在大于等于mid的数 return false

​ 由抽屉原理可知 因为要在m-1行里选m件物品 必然有一行是选了两件及以上的 若是不满足这个条件 return false

​ 因为当return false的时候 r是没有可能成为答案的 所以 r = mid - 1 相应的mid = l + r + 1 >> 1

Code:

bool check(vector<vector<int> > &mp, int x)
{
    vector<bool> st(m);

    bool pair = false;
    for(int i = 0; i < n; i++)//遍历行
    {
        int c = 0;
        for(int j = 0; j < m; j++)//遍历列
        {
            if(mp[i][j] >= x)     
                st[j] = true, c ++;
        }
        if(c > 1)   pair = true;
    }

    if(!pair)  return false;
    bool ans = true;
    for(auto t : st)   ans = ans && t;
    return ans;
}

void solve()
{
    int maxx = 0;
    cin >> n >> m;
    vector<vector<int> > mp(n, vector<int>(m));
    
	for (int i = 0;  i < n; i ++)
		for (int j = 0; j < m; j ++)
		    cin >> mp[i][j], maxx = max(maxx, mp[i][j]);
	
    int l = 1, r = maxx;
    while(l < r)
    {
        int mid = (l + r + 1) >> 1;
        if(check(mp, mid))  l = mid;
        else r = mid - 1;
    }
    cout << l << endl;
}

E MEX and Increments(模拟 + 思维)

Description:

​ 给定长度为n的序列 我们可以对序列进行op操作 : 任选一个数给他加上一

​ 如果我们通过op能够构造出MEX == k (0 <= k <= n) 输出op的次数

​ 反之输出-1

​ MEX 的意思就是数组中最小的不存在的数

Method:

​ 简化题目 题目的目的是空出第k个数 那就意味着任何0~k-1都要存在于数组中 并使k不存在数组中

​ 使k不存在于数组中非常简单 直接把k+1即可

​ 我们着重来讨论一下前面一种情况

​ 因为我们从0开始询问是否能构造出NEX 所以当MEX == k成立的时候 0~k-1是必然存在的

​ 这时询问下一个k的时候 如果能从0~k - 2中选出一个填到k - 1 那就可以通过了

​ 反之 若不能选出填补k - 1 那后面也不需要在看了 永远都无法补全了

​ 观察一下样例 样例3和4在第一次出现-1之后一直都是-1 结合分析 得到猜想 在一次-1以后都是-1

​ 我们的解题思路是 如何来判断是否能填上那个空

​ 当MEX == k时 我们只需要查看k - 1是否能够存在 因为MEX == k - 1的时候 0~k - 2必然存在了

​ 若是0~k - 2中含有多余的元素补上k-1这个空 那么MEX == k就可以成立

​ op数 = 补到k - 1需要的op + k的个数

​ 注意的是op数是每次MEX中叠加的 为什么呢 因为每次取得MEX的操作是可以继承到下一次的

Code:

const int N = 200010;
int n;
stack<int> st;
int q[N], num[N];
LL f[N];

void init()
{
    for(int i = 0; i <= n; i++)
        num[i] = 0;
    while(st.size())    st.pop();
}

void solve()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> q[i], num[q[i]] ++;//记录个数
    sort(q + 1, q + n + 1);//排序

    for(int i = 0; i <= n; i++) f[i] = -1;//初始化就设为-1 比较方便

    LL sum = 0;
    for(int k = 0; k <= n; k++)
    {
        if(k > 0 && num[k - 1] == 0)//k - 1 >= 0且k - 1为0
        {
            if(st.empty())  break; //找不到多余的来补充
            int t = st.top(); //栈顶一定是离得最近的 最适合取用
            st.pop();
            sum += k - 1 - t;
        }
        f[k] = sum + num[k]; // t -> k - 1 + k -> k + 1
        while(k > 0 && num[k - 1] > 1) //把多余的加入到栈中等待取用
            num[k - 1] --, st.push(k - 1); 
    }

    for(int i = 0; i <= n; i++)
        cout << f[i] << (i == n ? '\n' : ' ');
    init();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<div id="wea_rich_text_default_font" style="font-family:微软雅黑;font-size:12;"><p><img alt="" src="/weaver/weaver.file.FileDownload?fileid=aaa9aee4717d33272bd7ea028fa03118b693919f23b18febf9f6cee1158e8f4cf027542c71c8cf98d63770ccdf3bd1750e6b92e28c43dccd4" /></p><div class="ckeditor-html5-video" data-widget="html5video" style="text-align:left"><video controls="controls" src="/weaver/weaver.file.FileDownload?fileid=aad6f413f83191673980c5ee24b412880d6b9e8703caca411faec3276fe8133f5fa7e34630ca89ace63770ccdf3bd175071362141037cfb4e&download=1" style="max-width:100%"> </video></div><table border="1" cellpadding="1" style="width:500px;"> <tbody> <tr> <td style="padding: 1px;">1</td> <td style="padding: 1px;">1</td> </tr> <tr> <td style="padding: 1px;">2</td> <td style="padding: 1px;">2</td> </tr> <tr> <td style="padding: 1px;">3</td> <td style="padding: 1px;">3<a href="http://localhost:8080/wui/index.html#/main/portal/portal-1-1?menuIds=0,1&menuPathIds=0,1&_key=zq8830" target="_blank">http://localhost:8080/wui/index.html#/main/portal/portal-1-1?menuIds=0,1&menuPathIds=0,1&_key=zq8830</a></td> </tr> </tbody></table><p>测试<a href="http://localhost:8080/wui/index.html#/main/portal/portal-1-1?menuIds=0,1&menuPathIds=0,1&_key=zq8830" target="_blank">http://localhost:8080/wui/index.html#/main/portal/portal-1-1?menuIds=0,1&menuPathIds=0,1&_key=zq8830</a></p><p> </p><p>修改一下吧 qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq<img alt="" src="/weaver/weaver.file.FileDownload?fileid=a7617945ec5f52ec80aaa43ee8504de0a1b14d5eca4a98834494c85349762c626dec7ba8d0da277106ee600d27743f4e44f710fbddd167603" /></p></div>
06-01

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值