acwing周赛39-42(水题实录)
39.第一次打acwing
实话实说,acwing这个平台也还不错,虽然周赛有点水,但是可以增加我的信心加快我的代码速度与熟练度,还有就是对一些板子更加熟悉一点
a.水题
b.
题意:给你q行数据,每行两个字符串,为节点字符串与和这个节点直接相连的字符串,最后输出所有的链表头和尾。
我的思路:用两个map维护每一个链表头和链表尾即可
代码:
#include<bits/stdc++.h>
using namespace std;
unordered_map<string,string>head,tail;
int n;
int main(){
cin>>n;
while(n--){
string a,b;
cin>>a>>b;
if(!tail.count(a))head[a]=b,tail[b]=a;
else head[tail[a]]=b,tail[b]=tail[a],tail.erase(a);
}
cout<<head.size()<<endl;
for(auto& [a,b]:head)cout<<a<<' '<<b<<endl;
return 0;}
c.
题意:给n个字符串,如果字符串s1与s2中有至少一个公共字母,则归为同一类,这类关系具有传递性。问最后字符串能被划分为几类。
我的思路:开了一个并查集+一个map,并查集用来存26个字母的所属关系,map用于筛选掉没有出现过的字母,最后满足fa[i]==i且map中存过的i计入答案中即可
代码:
#include<bits/stdc++.h>
using namespace std;
int fa[26],mp[26]={0};
int find(int x){
if(fa[x]==x)return x;
else return find(fa[x]);
}
int main(){int cnt=0;
int m;cin>>m;
for(int i=0;i<26;i++){
fa[i]=i;mp[i]=0;}
for(int i=0;i<m;i++){
string s;cin>>s;
for(int j=0;j<s.length();j++){
fa[find(s[j]-'a')]=find(s[0]-'a');
mp[fa[s[0]-'a']]++;
}
}
for(int i=0;i<26;i++){
if(mp[find(i)]&&find(i)==i)cnt++;
}
cout<<cnt<<endl;
return 0;}
40
很久后才补的题解,确实是没啥印象了。
a.黑曜石-岩浆
b.
大意是给一个整数序列,每次对一个数进行加减1的操作,问最少多少次操作能使序列中个数互不相同。
这个题我开map被卡了,一直换思路,最后ac后发现只要开一个unordered_map就能过
我的思路:先把序列中的数及其出现次数用map记录下来,然后升序排序,遍历序列,如果i重复出现了k次(k个i)那么从i+1,i+2,..i+k每个位置放一个,总共需要1+2+...+n次操作
代码:
#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
int a[6010];
int main(){
int n;cin>>n;
for(int i=0;i<n;i++){cin>>a[i];
if(!mp.count(a[i]))mp[a[i]]=1;
else mp[a[i]]++;}
sort(a,a+n);
int cnt=0;
/*for(int i=1;i<n;i++){
if(mp[a[i]]>1){
for(int j=1;j<=mp[a[i]]-1;j++){
mp[j]++;cnt+=j;
}mp[a[i]]=1;
}
}*/
for(int i=1;i<=n*2;i++){
if(!mp.count(i)||mp[i]==1)continue;
else{
for(int j=1;j<=mp[i]-1;j++){
if(mp.count(i+j))mp[i+j]++;
else mp[i+j]=1;cnt+=j;
}mp[i]=1;
}
}
cout<<cnt<<endl;
return 0;}
然后有个更暴力的做法,就是如果i重复k次,就直接让i+1加上k-1
a题竟然WA了两发,着实是有点心急而导致翻车
b.
https://www.acwing.com/problem/content/submission/code_detail/11570173/
大意是给你一个二维平面上的n个点,给一个基准点,问你总共有多少条过基准点和n个点中一点的直线。时间有些久远,我已经忘却我怎么WA的了 QAQ
其实这题挺水的,用pair<int,int>存一下x,y坐标,把斜率用map存起来即可
#include<bits/stdc++.h>
#define ll long long
using namespace std;
pair<int,int>a[1010],b[1010];
map<double,int>mp;
double c[1010];
int main(){
int n,x,y;int cnt=0;
cin>>n>>x>>y;
for(int i=1;i<=n;i++)cin>>a[i].first>>a[i].second;
for(int i=1;i<=n;i++){
b[i].first=a[i].first-x;
b[i].second=a[i].second-y;
if(b[i].first){
c[i]=double(b[i].second)/double(b[i].first);
if(!mp[c[i]])mp[c[i]]=1;
else cnt++;}
else {
if(!mp[100000])mp[100000]=1;
else cnt++;
}
}
cout<<n-cnt<<endl;
return 0;}
42
这次状态不怎么样,有点卡题~
老规矩,a题水题
b.
大意是给你两个字符串,q次询问s1的[l,r]中有几个s2
数据范围:(wssb,写博客的时候才发现我把n,m范围看错了,我说我怎么一直segmation fault,气抖冷)
s1,s2,长度 1<=n,m<=1000,1<=q<=\(10^{5}\)(啊啊啊我看成30%的数据范围了)
我的思路:q较大,因此尽量离线操作,在询问前先处理出结果
处理形式为n*n数组,记录从各个左端点到右端点的ans
建立一个ok数组,初始化为1,遍历s1,如果s1[i]==s2[0],遍历s2比对,匹配失败则ok[i]=0;
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){int ok[50],cnt[50][50]={0};
for(int i=0;i<50;i++)ok[i]=1;
int n,m,q;
cin>>n>>m>>q;
string s1,s2;
cin>>s1>>s2;
for(int i=0;i<n;i++){
if(i+m>n){
ok[i]=0;continue;
}
else if(s1[i]==s2[0]){
for(int j=i;j<i+m;j++){
if(s1[j]!=s2[j-i]){
ok[i]=0;break;}
}}
else {ok[i]=0;continue;
}}
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
for(int k=i;k<=j;k++){
if(ok[k]&&k+m-1<=j)cnt[i][j]++;
}
}
}
for(int i=1;i<=q;i++){
int l,r;cin>>l>>r;
if(n<m||l>=r)cout<<"0"<<endl;
else cout<<cnt[l-1][r-1]<<endl;
//cout<<a[0]<<endl;
// for(int i=0;i<n;i++)cout<<ok[i]<<' ';
}
return 0;}
结果yxc直接搞了一个stl出来秒杀了这个题,我的内心是崩溃的,化身愤怒的罚时巨兽~~
y总代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m, Q;
string S, T;
char strs[N], strt[N];
int s[N];
int main()
{
scanf("%d%d%d", &n, &m, &Q);
scanf("%s%s", strs, strt);
S = strs, T = strt;
S = ' ' + S;
for (int i = m; i <= n; i ++ )
{
s[i] = s[i -1 ];
if (S.substr(i - m + 1, m) == T)
s[i] ++ ;
}
while (Q -- )
{
int l, r;
scanf("%d%d", &l, &r);
l += m - 1;
if (l > r) puts("0");
else printf("%d\n", s[r] - s[l - 1]);
}return 0;
}
知道了string.substr()这个函数之后这题也很水了,主要再学习一些y总的思路:
处理从1到i的ok[i],用前缀和给出ans,时间复杂度为o(n)