鏈接: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;
}