A.Sum of Odd Integers
题目大意:给你两个正整数n和k。让你判断能否找到k个不同的正奇数使得它们的和为n。
题解:容易得出k各不同的正奇数之和至少为
k
∗
k
k*k
k∗k(即1,3,5…2k-1),所以n必须满足
n
>
=
k
∗
k
n>=k*k
n>=k∗k。然后k个奇数之和奇偶性是确定的,还要满足
n
n
n%
2
=
=
k
2==k
2==k%
2
2
2(注意
k
∗
k
k*k
k∗k会爆
i
n
t
int
int)。
#include<bits/stdc++.h>
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
void solve()
{
ll n,k;
scanf("%lld %lld",&n,&k);
if(n>=k*k&&(n-k*k)%2==0)
printf("YES\n");
else printf("NO\n");
}
int main()
{
int t;scanf("%d",&t);while(t--)
solve();
return 0;
}
B.Princesses and Princes
题目大意:有
n
n
n个公主和
n
n
n个王子,编号都为
1
1
1~
n
n
n。每个公主都只愿意和部分王子结婚,并且她们会优先选择编号较小的王子,每个王子只能被选择一次。我们会让编号较小的公主开始先做选择,知道所有公主选择完毕。但是这样可能会导致剩下一些公主和王子没配对,这时候你作为国王可以让一个公主再爱上一个王子,尽可能多的增加配对数。
题解:先看一下能不能完全匹配,如果不能,在没有匹配当中任意输出一个公主和王子就好了,保证能多增加一对。
#include<bits/stdc++.h>
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
vector<int> v[maxn];
set<int> si;
void solve()
{
int n;
scanf("%d",&n);
si.clear();
for(int i=1;i<=n;i++)
v[i].clear();
for(int i=1;i<=n;i++)
{
int k;
scanf("%d",&k);
for(int j=1;j<=k;j++)
{
int temp;
scanf("%d",&temp);
v[i].push_back(temp);
}
}
int ans1=0,ans2=0;
for(int i=1;i<=n;i++)
{
int j;
for(j=0;j<v[i].size();j++)
{
if(!si.count(v[i][j]))
{
si.insert(v[i][j]);
break;
}
}
if(j==v[i].size()&&!ans1)
ans1=i;
}
if(!ans1)
printf("OPTIMAL\n");
else {
printf("IMPROVE\n");
for(int i=1;i<=n;i++)
if(!si.count(i))
{
ans2=i;
break;
}
printf("%d %d\n",ans1,ans2);
}
}
int main()
{
int t;scanf("%d",&t);while(t--)
solve();
return 0;
}
C.Game with Chips
题目大意:在一个
n
∗
m
n*m
n∗m的网格中有k个碎片,给你每一个碎片的起点坐标以及他们需要到达的终点坐标。你有四种操作,分别是将所有碎片向上、向下、向左、向右移动一个单位(但不能超出边界)。要求你给出一种操作方案使的每一个碎片到达过自己所对应的终点,且要求操作数不能超过
2
m
n
2mn
2mn。
题解:这道题目看上去很难,好像要没一个碎片单独考虑。然而其实你只要先把所有碎片汇集到同一个格子比如左上角(做多需要
n
+
m
−
2
n+m-2
n+m−2步操作),然后你就可以让所有碎片一起动,遍历完所有方格就好了。总共需要
m
n
+
m
+
n
−
3
mn+m+n-3
mn+m+n−3步操作,肯定是比题目所要求的
2
m
n
2mn
2mn要小的。
#include<bits/stdc++.h>
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
void solve()
{
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
int x,y;
for(int i=1;i<=k;i++)
scanf("%d %d",&x,&y);
for(int i=1;i<=k;i++)
scanf("%d %d",&x,&y);
printf("%d\n",m*n+m+n-3);
for(int i=1;i<=m-1;i++)
printf("L");
for(int i=1;i<=n-1;i++)
printf("U");
for(int i=1;i<=m;i++)
{
if(i&1)
for(int i=1;i<=n-1;i++)
printf("D");
else
for(int i=1;i<=n-1;i++)
printf("U");
if(i!=m)
printf("R");
else printf("\n");
}
}
int main()
{
//int t;scanf("%d",&t);while(t--)
solve();
return 0;
}
D.Infinite Path
没做出来
E.Count The Blocks
题目大意:有一串整数,从
0
0
0到
1
0
n
−
1
10^n-1
10n−1。如果该数不足n位的则在其前面用0补足。长度为L的块的定义为在一个数中连续L位数字为相同的数字,且不能向左右扩展(这一段左右没有数字或数字不同)。让你分别求出长度为1到长度为n的块的数目,答案对
998244353
998244353
998244353取余。
题解:首先长度为n的块的数目很好求,很明显是
10
10
10。然后从后往前推你就会发现能推出公式。
a
n
s
=
10
∗
9
∗
2
∗
1
0
(
n
−
i
−
1
)
+
9
∗
9
∗
(
n
−
i
−
1
)
∗
1
0
(
n
−
i
−
2
)
ans=10*9*2*10^{(n-i-1)}+9*9*(n-i-1)*10^{(n-i-2)}
ans=10∗9∗2∗10(n−i−1)+9∗9∗(n−i−1)∗10(n−i−2)(i=n和i=n-1时候需要特殊判断)。
#include<bits/stdc++.h>
using namespace std;
#define IOS std::ios::sync_with_stdio(false)
typedef long long ll;
const int maxn=1e5+5;
const int mod=998244353;
ll pow_bound(ll a,ll k)
{
if(k==0)
return 1;
ll temp=pow_bound(a,k/2);
ll ans=temp*temp%mod;
if(k&1)
ans=ans*a%mod;
return ans;
}
void solve()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
if(i==n)
{
printf("10\n");
continue;
}
if(i==n-1)
{
printf("180 ");
continue;
}
ll ans=0;
ans+=10*9*2*pow_bound(10,n-i-1);
ans%=mod;
ans+=10*9*9*(n-i-1)*pow_bound(10,n-i-2);
ans%=mod;
printf("%lld",ans);
if(i==n)
printf("\n");
else printf(" ");
}
}
int main()
{
//int t;scanf("%d",&t);while(t--)
solve();
return 0;
}
刚开始写这种题解,水平能力也有限,大家要是有什么意见或建议可以写在评论区,估计看的人都没有吧。