Codeforces Round #599A~D题解

Maximum Square

在这里插入图片描述
这是一道很简单的题目大意就是说给你一个几个木棍拼成一串问你从中扣出一个正方形的最大边长是多少
二分简单枚举一下可能的长度再判断一下就好了

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e3 + 10;
int k, T;
int a[N];

bool check(int mx)
{
    int ans = 0;
    for(int i = 0; i < k; ++ i)
      if(a[i] >= mx) ans ++;
      
      if(ans >= mx) return true;
      else return false;
}

int ans()
{
    int l = 0, r = k;
    while(l < r)
    {
        int mid = (l + r + 1 )>> 1;
        if(check(mid)) l = mid;
        else r = mid - 1;
    }
    return r;
}

int main()
{
    cin >> T;
    
    while(T --)
    {
        cin >> k;
        for(int i = 0; i < k; ++ i)
         cin >> a[i];
         sort(a, a + k);
         cout << ans() << endl;
    }
}

Character Swap (Easy Version)

在这里插入图片描述
在这里插入图片描述
题目大意就是说给你两个字符经过一次交换两个字符串中的任意位置的字母后是否可以达到相同
1.如果不是两个位置不一样一定是no
2,如果两个位置不一样但是字母不是对应相同就no否则就是Yes

#include <iostream>
#include <cstring>

using namespace std;
const int N = 1e4 + 10;
int T, n;
char ch[N];
char a[N];
int ma[N];//记录不相同点的位置
int num, k;
int main()
{
   cin >> T;
   
   while(T --)
   {
       num = 0;
       k = 0;
       cin >> n;
       
       for(int i = 0; i < n; ++ i)
         cin >> a[i];
       
       for(int i = 0; i < n; ++ i)
       {
           cin >> ch[i];
           if(ch[i] != a[i]) num ++, ma[k ++] = i;
       }
       
       if(num == 2) 
       {
           if(a[ma[0]] == a[ma[1]] && ch[ma[0]] == ch[ma[1]])
            cout << "Yes" << endl;
        else cout << "No" << endl;
       }
       else cout <<"No" << endl;
       
   }
   
   return 0;
}

在这里插入图片描述
在这里插入图片描述
跟easy部分有点不同就是说你可以最多交换2 * n次之后是否相同可以达到相同如果可以就输出交换的过程
解题思路:
1.首先判断一下两个串中的字母出现的次数是否是偶数次
2.如果是我们简单模拟一下先将第一列对其再将第二列对其以此类推因为字符串的长度才50所以模拟是可以过的

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
typedef pair<int,int> PII;
const int N = 1e4 + 10;
int T, n, num;
int vis[N];
char ch[N],a[N];
bool  flag;
PII p[N];//用pair记录交换路径
int main()
{
    std::ios::sync_with_stdio(0);
    cout.tie(0);
    cin.tie(0);
    
   cin >> T;
   
   while(T --)
   {
       flag = true;
       num = 0;
       cin >> n;
       
       for(int i = 0; i < n; ++ i)
       {
           cin >> a[i];
           vis[a[i] - 'a'] ++;
       }
         
         
       for(int i = 0; i < n; ++ i)
       {
           cin >> ch[i];
           vis[ch[i] - 'a'] ++;
       }
       
       for(int i = 0; i < 26 && flag; ++ i)
        if(vis[i] % 2)//进行第一步
        {
          cout <<"No" << endl;
          flag = false;
        }
        //...................................................................
        memset(vis,0,sizeof(vis));
        if(!flag) continue;
        int id;
        for(int i = 0; i < n; ++ i)
        //首先枚举第一行的字符串
        {
            flag = false;
            id = i + 1;
            if(a[i] == a[i + 1] && ch[i] == ch[i + 1])
            {
                if(a[i] != ch[i])
                p[num ++] = {i,i + 1};
                i ++;
                continue;
            }
            //因为你的匹配字符串的可能是在原串也可能在下面
            for(int j = i; j < n; ++ j)
            {
                if(a[i] == ch[j] && j == i)
                {
                    flag = true;
                    break;
                }
                if(a[i] == ch[j])
                {
                  while(a[id] == ch[id]) id ++;//模拟一下找到右边第一个不对齐的点将其交换
                  swap(a[id],ch[j]);
                  p[num ++] = {id,j};
                  swap(ch[i],a[id]);
                  p[num ++] = {id,i};
                  flag = true;
                  break;
                }
            }
            if(!flag)
                for(int k = i + 1; k < n; ++ k)
                    if(a[i] == a[k] && a[k] != ch[k])
                    {
                        swap(a[k],ch[i]);
                        p[num ++] = {k,i};
                    }
        }
        //...................................................................
        if(num > 2 * n)  cout << "No" << endl;
        else 
        {
            cout << "Yes" << endl;
            cout << num << endl;
            for(int i = 0; i < num; ++ i)
              cout << p[i].first + 1<< " " << p[i].second + 1<< endl;
        }
   }
   
   cout.flush();
   return 0;
}

Tile Painting

在这里插入图片描述
一道数学题其实自己手动模拟一下可以找到规律
给你一个长度为n的路径,路径有一个个小方格,就是说n % (i - j) == 0 && i - j > 1 的i 和 j的方格涂相同的颜色,问你最多涂多少种颜色

解题思路:
1.因为n’%(i - j) == 0 所以i - j 就是n的因子
2.将n分解质因子
3.那么循环节是多少呢 lcm(所有的质因子)= n
4.那么循环长度就是 n / lcm == 1;
我们还有处理一下质因子只有一个的情况

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;
typedef long long LL;

LL n, m;
int main()
{
  cin >> n;
  if(n == 1) 
  {
      cout << "1" << endl;
      return 0;
  }
  for(LL i = 2; i * i * 1ll  <= n; ++ i)
     if(n % i == 0)
     {
         ans.push_back(i);
         while(n % i == 0) n /= i;
     }
     if(n > 1) ans.push_back(n);
     if(ans.size() == 1) cout << ans.back() << endl;
     else  cout << "1" << endl;
     return 0;
}

0-1 MST

在这里插入图片描述
如果数据范围小的话就是一道最小生成树的裸题但是数据范围比较大所以我们要用dfs模拟克鲁斯卡尔算法
因为边权只有1和0这两个数字所以对于边权没有1的点我们可以看成一个·点就是缩点缩
点 因为根据克鲁斯卡尔的算法思路就是如果两个点边权有0之后一定会选择0这条边去连接 再去求联通块的数目就好 再减一就是答案(最小生成树边个数 = 点个数 - 1

#include <iostream>
#include <set>
#include <vector>

using namespace std;
const int N = 1e5 + 10;
bool u[N];
set<int> g[N];
set<int> vis;

void dfs(int x)
{
    u[x] = 1;//标记访问
    vis.erase(x);
    vector<int> ret;
    for(auto p : vis)
     if(!g[x].count(p))
       ret.push_back(p);
       
       for(int i : ret)
           vis.erase(i);
    for(int t : ret)
    {
        u[t] = 1;
        dfs(t);
    }
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; ++ i)
    {
        int x, y;
        cin >> x >> y;
        x --, y --;//把边权有1的点删掉
        g[x].insert(y);
        g[y].insert(x);
    }
    for(int i = 0; i < n; ++ i)//表示有哪些点没有被访问过
      vis.insert(i);
      int ans = 0;
      for(int i = 0; i < n; ++ i)
       if(!u[i])
       {
           ans ++;
           dfs(i);
       }
       cout << ans - 1 << endl;
       
       return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值