Dashboard - Educational Codeforces Round 104 (Rated for Div. 2) - Codeforces
1.
这很明显找规律的题。分情况讨论
第一种情况是偶数,两个人永远碰不到。所以就是直接计算就好
第二种情况是奇数,如果是奇数,那两只猫肯定会相遇的,相遇一次多跳一格,计算上这个就好了。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
ll n,k;
void slove(){
cin>>n>>k;
if(n%2){//
//如果是奇数也就是每走[n/2取整]步,就会跳一步
ll t=(k-1)/(n/2);//多跳的步
t+=(k-1);
cout<<t%n+1<<endl;
}
else{
cout<<(k-1)%n+1<<endl;
}
}
int main(){
int t;
cin>>t;
while(t--){
slove();
}
return 0;
}
2.
又是个找规律的题。
我们发现如果是奇数只队伍,那就总共举办n*(n-1)场比赛,每只队伍需要进行n-1场比赛,发现这个比赛场次是偶数,所以每只队伍选择赢n-1/2,输n-1/2
如果队伍数量是偶数,每只队伍也是进行n-1场比赛,但是这就变成了奇数,那就选择赢n-1/2,输n-1/2,剩下的平局。
然后最后贪心的先保证前面的队伍先把胜场打完,再打平局,再打输局就可以了。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
//如果n是奇数,只要要赢n/2,输n/2
//n是偶数,赢n-1/2,输n-1/2,平一局。
//每个人保证自己先赢在平再输,最后的结果也是正确的
int n;
void slove(){
cin>>n;
if(n%2){
for(int i=1;i<=n-1;i++){
for(int j=i+1;j<=min(n,i+n/2);j++){
cout<<1<<" ";
}
if(i<=n/2){
for(int j=i+n/2+1;j<=n;j++){
cout<<-1<<" ";
}
}
}
}
else{
for(int i=1;i<=n-1;i++){
for(int j=i+1;j<=min(n,i+(n-1)/2);j++){
cout<<1<<" ";
}
if(i<=n/2){
cout<<0<<" ";
for(int j=i+n/2+1;j<=n;j++){
cout<<-1<<" ";
}
}
}
}
}
int main(){
int t;
cin>>t;
while(t--){
slove();
}
return 0;
}
3.
这个题就更简单了,就是求一个直角三角形a,b,c(c是斜边)满足c=a^2-b
我们先写写勾股定理a^2+b^2=c^2
$$
\begin{cases}{a^2}=c+b\\ {a^2}=c^2+b^2\\ \end{cases}
$$
\begin{cases}{a^2}=c+b\\ {a^2}=c^2+b^2\\ \end{cases}
$$
化建之后也就是
$$
\begin{cases}{a^2}=c+b\\ {a^2}=(c+b)*(c-b)\\ \end{cases}
$$
\begin{cases}{a^2}=c+b\\ {a^2}=(c+b)*(c-b)\\ \end{cases}
$$
所以c-b因该是1。那就很简单了,c-b=1,那a^2肯定是奇数,那a就是奇数了。
那就只需要枚举所有奇数只要他可以又两个相邻的数相加等于他,并且小于n就可以了。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
//感觉经过了一套有效论证
//应该是只要a是大于1的奇数就可以加+1
ll n;
void slove(){
cin>>n;
//看什么数的平方的一半会比n大,这样的数肯定就不行了
ll ans=0;
for(int i=3;i<=1e5+100;i+=2){
ll t=pow(i,2);
if(t/2+1>n) break;
ans++;
}
cout<<ans<<endl;
}
int main(){
int t;
cin>>t;
while(t--){
slove();
}
return 0;
}
4.
这个题可以这样考虑,我可以考虑将两个食品合并。每次找可以合并的最小价值的那个,这样最后在v[4] [0]就的到了最小的需要钱数。还有一点就是每个组合之间的限制是2e5的这也就可以近似的把第三个for循环看成O(n)的。
储存限制条件就用mp存就好了。定义一个二元组存储两个互斥食物的下标。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fel(i,x,y) for(int i=x;i<=y;i++)
#define fhl(i,x,y) for(int i=x;i>=y;i--)
#define inf 0x3fffffff
#define ll long long
#define pb push_back
#define endl "\n"
typedef pair<int,int>PII;
#define x first
#define y second
#define int long long
//这个题有个很不错的思路
//就是每次把前面一个菜和后面的和并
int num[5];
vector<PII>v[5];
map<PII,int>mp[5];
void slove(){
fel(i,1,4) cin>>num[i];
for(int i=1;i<=4;i++){
for(int j=1,x;j<=num[i];j++){
cin>>x;
v[i].pb({x,j});
}
}
for(int i=2,m,x,y;i<=4;i++){
cin>>m;
for(int j=1;j<=m;j++){
cin>>x>>y;
mp[i][{x,y}]=1;
}
}
for(int i=2;i<=4;i++){
sort(v[i-1].begin(),v[i-1].end());
for(int j=0;j<num[i];j++){//限制没两组限制只有2e5所以这复杂度因该是O(n)的
int k=0;
while(k<num[i-1]&&mp[i][{v[i-1][k].y,v[i][j].y}]) ++k;
if(k==num[i-1]) v[i][j].x=inf;
else v[i][j].x+=v[i-1][k].x;
}
}
sort(v[4].begin(),v[4].end());
cout<<(v[4][0].x>=inf?-1:v[4][0].x)<<endl;
}
signed main(){
IOS
int t=1;
//cin>>t;
while(t--){
slove();
}
return 0;
}

浙公网安备 33010602011771号