20241003
赛时得分
| 题目 | A | B | C | D | 总分 | 排名 | 比例 |
|---|---|---|---|---|---|---|---|
| 满分 | 100 | 100 | 100 | 100 | 400 | 170 | 100% |
| 得分 | 100 | 90 | 15 | 0 | 205 | 40 | 23.5% |
A. 预测星星(100/100)
\(\text{100%}\) 得分做法,我们考虑统一将所有时间转化为分钟形式,然后开两个 multiset 维护一周内所有可能的循环到的时间节点,将两个星星的这些时间点分别存储到这两个集合中。
接着我们比较两个集合,如果有相同元素,我们直接转化成 HH:MM 形式输出,没有则输出 Never 即可。对于日期的判断,我们直接开一收大小为 \(7\) 的字符串数组,最后计算时间\(\text{ mod }7\) 维护即可。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
ll h1,m1,h2,m2,lh1,lm1,lh2,lm2,same=-1,st1,st2,t1,t2,anst;
char c;
string s[]={"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
set<ll> a,b;
void print(ll x)
{
if(x<10) cout<<"0"<<x;
else cout<<x;
return;
}
int main()
{
freopen("star.in","r",stdin);
freopen("star.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>h1>>c>>m1>>h2>>c>>m2>>lh1>>c>>lm1>>lh2>>c>>lm2;
st1=h1*60+m1,st2=h2*60+m2,t1=lh1*60+lm1,t2=lh2*60+lm2;
for(int i=0;i<=20000;i++)
{
a.insert(st1+i*t1);
b.insert(st2+i*t2);
}
for(auto i:a)
{
if(b.find(i)==b.end()) continue;
same=i;
break;
}
if(same==-1) cout<<"Never";
else
{
cout<<s[(same/1440)%7]<<endl;
anst=same%1440;
print(anst/60);
cout<<":";
print(anst%60);
}
return 0;
}
B. 机器人的检测(100/100)
\(\text{100%}\) 得分做法,我们用两个 map 分别维护每一行/列上面的点的个数,首先先预处理出最开始的总贡献,考虑将上下和左右分别操作,比如上下我们需要维护在当前列上面的监测点个数、在当前列下面的监测点个数以及当前列的监测点个数。接着不难发现向哪个方向操作,哪个方向的监测点距离贡献就 -1,当前列以及另一方向上所有点贡献就 +1;计算完贡献之后不断更新当前列即可。
赛时没有过这个题是评测机波动,其实是应该有 \(100\) 分的,不过确实没啥招。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=1e5+1;
ll n,m,x[N],y[N],tarx,tary,ans,cntd,cntu,cntl,cntr,nlr,nud;
string s;
bool ok=1;
map<ll,ll> mp1,mp2;
ll calc(ll x,ll y,ll xt,ll yt)
{
return abs(x-xt)+abs(y-yt);
}
int main()
{
freopen("robot.in","r",stdin);
freopen("robot.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
mp1[y[i]]++,mp2[x[i]]++;
if(x[i]!=0) ok=0;
if(x[i]<0) cntl++;
else if(x[i]==0) nlr++;
else if(x[i]>0) cntr++;
if(y[i]<0) cntd++;
else if(y[i]==0) nud++;
else if(y[i]>0) cntu++;
ans+=calc(x[i],y[i],0,0);
}
cin>>s;
for(int i=0;i<m;i++)
{
if(s[i]=='S')
{
ans+=(cntd-cntu+nud);
tary++;
cntd+=nud;
nud=mp1[tary];
cntu-=nud;
}
if(s[i]=='J')
{
ans+=(cntu-cntd+nud);
tary--;
cntu+=nud;
nud=mp1[tary];
cntd-=nud;
}
if(s[i]=='I')
{
ans+=(cntl-cntr+nlr);
tarx++;
cntl+=nlr;
nlr=mp2[tarx];
cntr-=nlr;
}
if(s[i]=='Z')
{
ans+=(cntr-cntl+nlr);
tarx--;
cntr+=nlr;
nlr=mp2[tarx];
cntl-=nlr;
}
cout<<ans<<endl;
}
return 0;
}
C. 猫猫 cpu 的缓存(15/100)
\(\text{15%}\) 得分做法,我们考虑直接二进制枚举我们选的位数,将所有合法方案得到的结果取 \(\text{min}\) 值即可。
#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=3e5+1;
ll n,k,m,a[N],minn=2147483647,maxn=-1;
ll check(string s)
{
set<ll> st;
for(int i=0;i<s.length();i++)
{
if(s[i]=='1')
{
for(int j=i+1;j<=i+k;j++) st.insert(j);
}
}
for(int i=1;i<=m;i++)
{
if(st.find(a[i])==st.end()) return -1;
}
return st.size();
}
void dfs(ll now,string s)
{
if(now>n-k+2) return;
if(now==n-k+2)
{
if(check(s)==-1) return;
else minn=min(minn,check(s));
}
dfs(now+1,s+"0");
dfs(now+1,s+"1");
return;
}
int main()
{
freopen("cpu.in","r",stdin);
freopen("cpu.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>k>>m;
if(n<=20 and m<=10)
{
for(int i=1;i<=m;i++) cin>>a[i];
dfs(1,"");
cout<<minn;
}
else
{
for(int i=1;i<=m;i++)
{
cin>>a[i];
maxn=max(maxn,a[i]);
minn=min(minn,a[i]);
}
cout<<maxn-minn+1;
}
return 0;
}

浙公网安备 33010602011771号