[24 ICPC ShaanXi](https://codeforces.com/gym/105257‘)

repo
file
感动,Shaanxi,感觉题目难度海星
队友们tql,俺基本没碰键盘,赛后补题ing

::F. Try a try, AC is OK:: 签到/位运算

1. 题意:

问 给定长度为n的序列中,两个可相同的元素的最大的,与运算的值。

2. 题解:

原本的思路:
取其中最大值&本身
答案显然为最大数字

::M. Window Decoration:: 签到/小学几何奥数(?)

1. 题意:

给定n个(<99) 对角线长度为2的矩形的 中点坐标
忽略重叠面积。
求总面积?

2. 题解:

原本的思路:
想法是对于每个矩阵的四个顶点到中点 建无向图。
其中,用一个set去重每个点的相同邻边
那么,ans=总边数/4.0;
赛时stl写宕机了(复习了一下)
学到的
分块标记,加入每一块的贡献,减去重复的贡献。简洁多了。tql。

3. code:

俺:

    map<pair<int ,int >, set<pair<int ,int > > > adj; 
    int _;cin>>_;
    while (_--) 
    {
        int x,y;cin>>x>>y;
        
        adj[{x, y}].insert({x,y+1});
        adj[{x, y}].insert({x,y-1});
        adj[{x, y}].insert({x+1,y});
        adj[{x, y}].insert({x-1,y});
       
        adj[{x, y+1}].insert({x,y});
        adj[{x, y-1}].insert({x,y});
        adj[{x+1, y}].insert({x,y});
        adj[{x-1, y}].insert({x,y});
    }
    
    int cnt=0;
    for (auto &[p,ne]:adj)
    {
        cnt+=ne.size();
    }
    
    cout<<cnt/4.0<<'\n';

    int _;cin>>_;
    
    int mp[111][111];
    double cnt=0.0;
    while(_--)
    {
        int x,y;cin>>x>>y;
        if(mp[x][y])continue;
        mp[x][y]++;
        cnt+=2.0;
        
        cnt-=0.5*(double)(mp[x-1][y]+mp[x+1][y]+mp[x][y+1]+mp[x][y-1]);
        
    }
    
    cout<<cnt<<'\n';

::A. chmod:: 签到/阅读理解/小模拟

1. 题意:

2. 题解:

原本的思路:
看题面看蒙了。
看样例终于懂了。
模拟题意即可。
学到的
我叽里咕噜写啥呢,打表吧孩子,没多少,还比较简洁

3. code:

        string s;cin>>s;
        
        for(int i=0;i<s.size();i++)
        {
            f(s[i]-'0');//binary
            
            for(int j=2;j>=0;j--)
            {//rwx            
            //    cout<<"now: ";
            //    cout<<v[j]<<'\n';
                if(v[j]==1)
                {
                    if(j==2)
                    {
                        cout<<"r";
                    }else if(j==1)
                    {
                        cout<<"w";
                    }else
                    {
                        cout<<"x";
                    }
                }else
                {
                    cout<<"-";
                }
            }            
            
        }
        cout<<'\n';

打表:

    int _;cin>>_;
    string s[]={"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};
    while(_--)
    {
        char a,b,c;cin>>a>>b>>c;        
        cout<<s[a-'0']<<s[b-'0']<<s[c-'0']<<'\n';            
    }

::G. Disappearing Number*:: 找规律/数位DP

1. 题意:

求 [0,n]中,各个数位都<k ∈[1-9]的 数字的个数?

2. 题解:

原本的思路:
超烦这种题,太菜了,打了一波表,没找到规律
学到的
题解

  1. 若k=9,视作 九进制数,转化为十进制数+1输出
  2. 否则,把n中所有大于k的数位-1,再转化成①

3. code:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f3f3f3f3f
#define debug(x) cout<<"#:"<<x<<'\n';

#define int long long
const int N=1e6+10;

signed main()
{

    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    
    int _;cin>>_;
    while(_--)
    {
        string s;cin>>s;
        int k;cin>>k;
        
        int ans=0;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]-'0'>k)
            {
                s[i]--;
            }            
            ans=ans*9+s[i]-'0';
        }        
        cout<<ans+1<<'\n';
    }    

    return 0;
}

::C. Seats*:: 图论

1. 题意:

有编号1-2n 的座位,一座一人。
给定 坐在第i号位置的人的 期望座位ai
若 期待位置上无人占座,那么可以选择调换位置 。否则,留在原位。
问 st 最大化 坐在期望的位置的人的数量?

2. 题解:

原本的思路:
对于样例,朴素的第一眼想法,就是对于同一个位置不可以产生冲突。用set维护去重。wa了()
反思:
但是,我实质上只是统计了 不同期望座位的个数 而已。
我忽略了 抢占 的问题
比如说,对于这个样例:
i: 1 2 3 4
ai: 2 3 4 4
其中,因为3号同学和4号同学都想去4号座位,
一种移动方案:
因为 4号同学期望相符,所以就懒得动了,
那么,就会导致3号同学,期望的四号位被卡,也不动了了,
同理,2号和1号同学也被卡了。
所以,实际结果=1 ,而不是3
具体思路:

  1. 对于最优情况:即对于当每个人的期望位置都不同的情况下,显然都可以满足。
    那么,核心就在于 存在有多个人选同一个位置的矛盾了。
  2. 对于 第i号同学,所期望的ai号座位的关系,考虑连边建图:
    i -> a[ i ]
  3. 观察图的出现的 两种结构:
    因为,每个人都有一个理想座位,
    所以,每个节点只有一条出边。
    1.:(有向树)
    选取最长的 一条终点为n+1~2*n的节点的链。
    2.
    只有环上的节点可以移动,计入对答案的贡献。

3. code:

    int n;cin>>n;
    int tot=n<<1;
    
    vector<vector<int > >g(tot+1);
    vector<int >in(tot+1,0);
    for(int i=1;i<=n;i++)
    {
        int ai;cin>>ai;
        g[i].push_back(ai);
        in[ai]++;
    }
        
    queue<int >q;
    for(int i=1;i<=tot;i++)
    {
        if(!in[i])q.push(i);
    }
        
    vector<int >mx(tot+1,0);
    vector<int >vis(tot+1,0);
    while(q.size())
    {
        int u=q.front();
        q.pop();
        
        vis[u]=1;
        
        for(auto v:g[u])
        {
            mx[v]=max(mx[v],mx[u]+1);
            
            if(!(--in[v]))
            {
                q.push(v);
            }
        }
    }
        
    int ans=0;
    for(int i=1;i<=tot;i++)
    {
        if(!vis[i])
        {
            ans++;//1. circle
        }
        
        if(!g[i].size())
        {
            ans+=mx[i];//2.chain
        }
    }
        
    cout<<ans<<"\n";

::L. Chess*:: 阅读理解/找规律

1. 题意:

博弈,a先手
一共 t轮;
每轮b给出一个x,
问 每轮最小的k?
st a必胜?

限定取的棋子的数量只能是lcn数

lcn?
k进制->位乘积d==数字a的因子

2. 题解:

3. code:

        int x;cin>>x;
        for(int i=2;;i++)
        {
            if(x%i!=0)
            {
                cout<<i<<'\n';
                break;
            }
        }

::B. Expression Matrix*:: 构造/快乐打表

1. 题意:

构造一个nm的只由"+","","1"组成的矩阵
st 每行每列字符串组成的合法的表达式求和最小
(3<=n,m<=9)

2. 题解:

原本的思路:
贪心,分奇偶,头大了,下次有空再看()

3. code:


posted @ 2025-04-25 19:26  积极向上到处睡觉  阅读(91)  评论(0)    收藏  举报