[24 ICPC ShaanXi](https://codeforces.com/gym/105257‘)
repo
感动,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. 题解:
原本的思路:
超烦这种题,太菜了,打了一波表,没找到规律
学到的
题解
- 若k=9,视作 九进制数,转化为十进制数+1输出
- 否则,把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
具体思路:
- 对于最优情况:即对于当每个人的期望位置都不同的情况下,显然都可以满足。
那么,核心就在于 存在有多个人选同一个位置的矛盾了。 - 对于 第i号同学,所期望的ai号座位的关系,考虑连边建图:
即 i -> a[ i ] - 观察图的出现的 两种结构:
因为,每个人都有一个理想座位,
所以,每个节点只有一条出边。
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:

浙公网安备 33010602011771号