链接:http://codeforces.com/contest/1327
A 问k个不相同的正奇数相加是否等于n,k个奇数相加的奇偶性一定与k相同,而且k个不相同的正奇数最小等于k^2 (1+3+…+2*k-1)判断一下就可以了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=100010;
int main()
{
ll t,n,k;//会爆int
cin>>t;
while(t--)
{
cin>>n>>k;
if((((n&1)&&(k&1))||(n%2==0&&k%2==0))&&n>=k*k) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
B 给n个公主找老公,模拟一遍就可以了,如果有公主没找到就再找任意一个没配对的王子就行了,样例n的总合不超过1e5不会超时
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=100010;
int t,n;
vector<int> g[N];
bool st[N];
int main()
{
IOS;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
int k,x;
cin>>k;
for(int j=0;j<k;j++)
{
cin>>x;
g[i].push_back(x);
}
}
int l=-1;//标记没配对的公主
memset(st,0,sizeof st);//标记王子
for(int i=1;i<=n;i++)
{
bool flag=0;
for(int j=0;j<g[i].size();j++)
if(!st[g[i][j]])
{
flag=1;
st[g[i][j]]=1;
break;
}
if(!flag) l=i;
}
if(l==-1)
{
cout<<"OPTIMAL"<<endl;
}
else
{
for(int i=1;i<=n;i++)
if(!st[i])
{
cout<<"IMPROVE"<<endl<<l<<' '<<i<<endl;
break;
}
}
for(int i=1;i<=n;i++)
g[i].clear();
}
return 0;
}
C 已知k个芯片的位置,每次将所有芯片向同一个方向移动(如过超出边界就不动)以格问是否可以让所有芯片都经过k个指定的位置,如果可以并且移动次数不超过2nm就输出移动的顺序(wtm看成了2纳米,???我就纳了闷了我是咋猪脑子嘛),否则输出-1
因为超出边界就不动,所以我们可以把所有芯片都移动到同一个位于边界位置,我是把他们都移动到点(1,1),假设位于对角的(n,m)有芯片就需要移动n-1+m-1次,不过(n,m)有没有这样移动都可以将他们全部移动到(1,1),就不判断了,而且移动方向与日常习惯不一样需要注意一下(血得教训啊),然后再从(1,1)向每一个指定位置移动就可以了,我排了个序,就会一行一行的移动,最坏情况是每一行的头尾都需要移动 2*(m-1)*(n-1)次,再加上开始的次数就是2nm-n-m-1,不会有-1的情况了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
const int N=1010;
int t,n,m,k;
int x[N],y[N];
string s;
struct node
{
int x,y;
}e[N];
bool cmp(node a,node b)
{
if (a.x==b.x)
return a.y<b.y;
else return a.x<b.x;
}
int main()
{
IOS;
cin>>n>>m>>k;
for(int i=1;i<m;i++) s.push_back('L');
for(int i=1;i<n;i++) s.push_back('U');
int l,r;
for(int i=0;i<k;i++) cin>>l>>r;//芯片的位置没有用到
e[0]={1,1};
for(int i=1;i<=k;i++)
cin>>e[i].x>>e[i].y;
sort(e,e+k+1,cmp);
for(int i=1;i<=k;i++)
{
l=abs(e[i].x-e[i-1].x);
r=abs(e[i].y-e[i-1].y);//到下一个指定位置横纵坐标分别需要移动的次数
if(e[i].x>=e[i-1].x)
{
for(int j=0;j<l;j++)
s.push_back('D');
}
else
{
for(int j=0;j<l;j++)
s.push_back('U');
}
if(e[i].y>=e[i-1].y)
{
for(int j=0;j<r;j++)
s.push_back('R');
}
else
{
for(int j=0;j<r;j++)
s.push_back('L');
}
}
cout<<s.size()<<endl<<s;
return 0;
}
D 不会,花了半小时看懂题意比赛也结束了,当时用的镜像网站看题没看过题人数,当个教训吧,一定要跟榜!!!其实看了e题当时大概率也是过不了hhh
E 统计0到10^n-1的块的个数(包括前导0)。
块的长度一定不超过n
先看n=1,1的个数就是10;
n=2,在n=1的基础上每个数前加一个相同的数,就是长度2的块了,所以长度2的块有10个,然后想0到99每个数有两位就需要2100个数字,块2(长度为2的块)有10个,消耗了210个数字,剩下了180个数字就都是块1了。
n=3,块3的个数和上面一样加一个相同的数还是有10个,刚好是n=2是块2的个数,这样可以发现一个规律,n时块i的个数等于n-1时i-1的个数(不会证明),这样可以求得块2到块n的个数,块1就和上面一样用总的出现的数字减块2到块n消耗的数字得到,一直向下推就可以了,
#include<iostream>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int N=200010;
ll n,a[N],sum[N],s[N];
ll ksm(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
b/=2;
a=a*a%mod;
}
return res;
}
int main()
{
cin>>n;
a[1]=10;
sum[1]=s[1]=10;
for(int i=2;i<=n;i++)
{
sum[i-1]=(sum[i-1]+s[i-1])%mod;
a[i]=(i*ksm(10,i)%mod-sum[i-1]+mod)%mod;
s[i]=(s[i-1]+a[i])%mod;
sum[i]=(sum[i-1]+a[i])%mod;
}
for(int i=n;i;i--)
cout<<a[i]<<' ';
return 0;
}