F、Capslock
#include<iostream>
#include<cstring>
#include<math.h>
#include<map>
#include<algorithm>
#define PI acos(-1)
using namespace std;
int main()
{
bool flag=0;
string s;
cin>>s;
for(int i=1;i<s.size();i++)
if(s[i]>'Z')//就是小写字母
flag=1;
if(flag==0)
{
if(s[0]>'Z')
s[0]-='a'-'A';
else s[0]+='a'-'A';
for(int i=1;i<s.size();i++)
s[i]+='a'-'A';
cout<<s<<endl;
}
else cout<<s<<endl;
return 0;
}
G、字节类型
这里get到了一个新用法,就是__int128,这个东西不能直接读入和输出,目前你只能用String类型来读入,然后再传到__int128类型里面。你可以直接拿它和其他的数来比较,但是不能直接输出;
还有一点要注意的是,题目已经说了他是正数,所以只用比较他们正数的部分就可以了。
#include<bits/stdc++.h>
using namespace std;
string a;
__int128 x=0;
int main()
{
cin>>a;
int len=a.size();
if(len>=20){
printf("BigInteger\n");
return 0;
}
for(int i=0;i<len;i++){
x=x*10+a[i]-'0';
}
if(x>9223372036854775807)printf("BigInteger\n");
else if(x>147483647)printf("long\n");
else if(x>32767)printf("int\n");
else if(x>127)printf("short\n");
else printf("byte\n");
return 0;
}
L、神奇的回答
这是一道简单的签到题!
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int a;
cin>>a;
if(a>=18)
cout<<"18"<<endl;
else cout<<a<<endl;
}
return 0;
}
E、生活大爆炸
这一题就是高中数学的排列组合,这一题我一开始就是把他的数学式子列出来,然后化为最简式,然后就可以发现其实就是几个阶层相除,但是这样子的话,好不容易用unsigned long long 把他给表示出来了,但是你要是再用除法的话,那样子肯定会emmm,反正我是没有输出结果的。所以这里就是用dp来,就是初始化dp数组,这里只要找到它的规律,那么一切好说。这里就是a[i][j]=a[i-1][j-1]+a[i-1][j],就是再来一个人,这个人可能被选中,也可能被被选中,然后把他的每一种情况相加,那么就保证的是从i+1个人里面选取j个人,然后这个新增的这个人可以选,也可以不选。
#include<bits/stdc++.h>
using namespace std;
const int N=65;
int n,m;
int a[N][N];//他的意思是从i个人里面选取j个人
void f()
{
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
{
if(!j)//就是选取0人就是
a[i][j]=1;
else a[i][j]=a[i-1][j-1]+a[i-1][j];//再加一个人,可以被选取,也可不被选取 }
}
}
int main()
{
ios::sync_with_stdio(false);
f();
cin.tie(0);
int n,m,t;
cin>>n>>m>>t;
long long ans=0;
for(int i=4; i<=n; i++)
for(int j=1; j<=m; j++)
if(i+j==t)
ans+=a[n][i]*a[m][j];
cout<<ans<<endl;
return 0;
}
后来看到了别人用排列组合的做法写出来了,后来才发现,自己不应该简化的,也不许构造数组。
#include<bits/stdc++.h>
#define ll __int128
using namespace std;
int n,m,t;
ll c(ll x,ll y){
if(y>x/2)y=x-y;
ll ret=1;
for(ll i=x;i>=x-y+1;i--)ret*=i;
for(ll i=1;i<=y;i++)ret/=i;
return ret;
}
int main()
{
cin>>n>>m>>t;
ll ans=0;
for(ll i=4;i<=min(n,t-1);i++){
if(t-i>m||t-i<1) continue;
ans+=c(n,i)*c(m,t-i);
}
int an[10000],cnt=0;
while(ans){
an[++cnt]=ans%10;
ans/=10;
}
for(int i=cnt;i>=1;i--){
printf("%d",an[i]);
}
return 0;
}
D、阿强与网格
纯模拟题。
wa的原因是n,m,x,y开的是int,开小了,我想着我ans开的long long 就没事了,但是他是10^5次方,然后相乘的话就会爆int,然后他就会变成随便的一个数,然后这个时候就要用long long来才可以。 学到了!get it!
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long n,m,x,y;
scanf("%lld%lld%lld%lld",&n,&m,&x,&y);
long long ans=0;
if(n<m)swap(n,m);
if(m==1)
{
ans=(n-1)*x;
printf("%lld\n",ans);
continue;
}
if(y>=2*x)
ans=(n+m-2)*x;
else if(y>=x)
ans=(n-m)*x+(m-1)*y;
else
{
if((n-m)%2==0)
ans=y*(n-1);
else ans=y*(n-2)+x;
}
printf("%lld\n",ans);
}
return 0;
}
C、传染病统计
模拟题!先排序,然后把相邻的两个的判断是否距离小于等于2,然后记录一下,从前往后遍历,然后,用cnt来记录一下这一段的长度,然后用这个cnt来维护最大值和最小值。
#include<bits/stdc++.h>
using namespace std;
const int N=15;
int a[N],b[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
b[n]=n;
for(int i=1;i<n;i++)
if(a[i+1]-a[i]<=2)b[i]=i+1;
else b[i]=i;
int ans=0,mx=0,mn=110;
for(int i=1;i<=n;i++)
{
ans++;
//cout<<b[i]<<" ";
if(b[i]==i+1)continue;
else {
mx=max(mx,ans);
mn=min(mn,ans);
ans=0;
}
}
memset(b,0,4*n);
printf("%d %d\n",mn,mx);
}
return 0;
}
还有线段树板子题II-完美主义_2021辽宁省大学生程序设计竞赛(正式赛)(重现赛)@JXNU_19_ACS (nowcoder.com)
dp题
J-放棋子_2021辽宁省大学生程序设计竞赛(正式赛)(重现赛)@JXNU_19_ACS (nowcoder.com)
待补!