写一个牛牛的题解:这场前三题很简单,d分类分了半天,分不清楚,感觉写的时候脑子很乱。
然后E骗了一点分,剩下的题再补补吧。
把D,E补一补,剩下的F以后再说了 --------- 2024.9.9
1.TD
没啥写的,保留小数,基础操作
void solve()
{
double n,m;
cin>>n>>m;
printf("%.8lf",n/m);
}
2.你好,这里是牛客竞赛
就是对于开头的网站进行匹配即可,后面的不需要管 用substr取下来即可
void solve()
{
string s;
cin>>s;
string t = s.substr(0,24);
string t1 = s.substr(0,23);
string t2 = s.substr(0,16);
string t3 = s.substr(0,15);
// cout<<t2<<" "<<t3<<" ";
if(t=="https://www.nowcoder.com" || t2=="www.nowcoder.com"){
cout<<"Nowcoder"<<endl;
}
else if(t1=="https://ac.nowcoder.com" || t3=="ac.nowcoder.com"){
cout<<"Ac"<<endl;
}
else{
cout<<"No"<<endl;
}
// cout<<t<<endl;
}
3.逆序数
手搓一下样例就会发现,正反序列相加的个数正好等于这个序列长度的C(n,2)个 所以减一下就可以了
void solve()
{
LL n,k;
cin>>n>>k;
LL ans = (n-1)*n/2;
cout<<LL(ans-k);
}
4.构造mex
要分类讨论的情况挺多的,而且一多就乱
超绝构造
1.判断k=0的时候
2.特判s==1&k==1 || s-k*(k-1)/2<0的情况
3.判断n与k的关系,然后再分三小块
个人感觉最难写的就是最后一块,n>k的情况
n>k里面再分res==k和res!=k讨论
细节挺多的,本人没考虑到2和res<0的情况
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
void solve()
{
LL s,n,k;
cin>>s>>n>>k;
LL sum = k*(k-1)/2;
if(k==0){
if(n>s){
cout<<"NO"<<endl;
return;
}
else{
cout<<"YES"<<endl;
for(int i=1;i<n;i++){
cout<<1<<" ";
}
cout<<s-(n-1)<<endl;
return;
}
}
LL res = s - sum;
if(s==1 && k==1){
cout<<"NO"<<endl;
return;
}
if(res<0){
cout<<"NO"<<endl;
return;
}
if(n<k){
cout<<"NO"<<endl;
return;
}
else if(n==k){
if(sum==s){
cout<<"YES"<<endl;
for(int i=0;i<k;i++){
cout<<i<<" ";
}
cout<<endl;
return;
}
else{
cout<<"NO"<<endl;
return;
}
}
else{
if(res==k){
if(n-k>1){
cout<<"YES"<<endl;
for(int i=0;i<k;i++){
cout<<i<<" ";
}
cout<<k-1<<" "<<1<<" ";
for(int i=k+3;i<=n;i++){
cout<<0<<" ";
}
cout<<endl;
return;
}else{
cout<<"NO"<<endl;
return;
}
}
else{
cout<<"YES"<<endl;
for(int i=0;i<k;i++){
cout<<i<<" ";
}
cout<<res<<" ";
for(int i=k+2;i<=n;i++){
cout<<0<<" ";
}
cout<<endl;
return;
}
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
5.小红的X型矩阵
启始,想的解法是n2暴力过去,发现无法做到o(1)计算对角线上的值(菜!)
随后,去b站看题解,来来回回1小时才弄明白(lll¬ω¬)
具体思路就是把矩阵抽象的拓展,但对于每次移动,对角线上的1的个数是不会变的(重点!),
然后用b,c,两个数组抽象为两个斜着的数的1的个数(很不好理解),感觉像是在求1的贡献。。。
最后判断一下奇数和偶数的情况就行了
void solve()
{
int n;
cin>>n;
vector<int> b(n+1,0),c(n+1,0);
vector<vector<int> > a(n+1,vector<int>(n+1,0));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
auto cal1 = [&](int x,int y){//左上到右下
return (x-y+n)%n;
};
auto cal2 = [&](int x,int y){//右上到左下
return (x+y)%n;
};
LL sum = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==1){
sum++;
b[cal1(i,j)]++;
c[cal2(i,j)]++;
}
}
}
LL ans = 1e7;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int t1 = cal1(i,j);
int t2 = cal2(i,j+n-1);
int tt = b[t1]+c[t2]-n%2*(a[(i+n/2)%n][(j+n/2)%n]==1);
ans = min(ans , sum-tt+2*n-n%2-tt);
}
}
cout<<ans;
}