尽快调整回来,这可能是你人生最重要的一年,好好审视自己,拎得清一点,丢弃掉无谓的担心,清楚自己在做什么。
既然大二有能力去做好一些事,那么大三就更没必要畏首畏尾,认真做好每一件事,还是那句话,把握好你能掌控住的东西,脚踏实地得努力实现。只要愿意去做,就一定能做好,待人可以平和,但是心气不能掉,懒惰会毁掉一个人。
再做不到,直接remake去吧
J. Eat, Sleep, Repeat
思路还算简单,只有出现次数从0开始连续向上的数,才会卡住一些数让他们不能递减。
代码我敲的很卡,不知道怎么写好。
代码思路:
1.使用map存下所有的限制条件,单独筛选出出现次数为0的数字存到数组中记为id。
2.对于数组a和数组id都进行降序排列。对数组id进行循环,为每个数组a中数字找到下界。
3.对数组a进行循环,不断向上取,每一个数有mp进行数量限制。
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =7e5+5;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-8;
int n,k,m,a[N],id[N],vis[N];
struct node
{
int val,cnt;
}e[N];
bool cmp(int a,int b){return a>b;}
map<int,int>mp;
void solve()
{
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=0;i<=n;i++) id[i]=vis[i]=0;
mp.clear();
m=0;
for(int i=1;i<=k;i++)
{
cin>>e[i].val>>e[i].cnt;
mp[e[i].val]=e[i].cnt;
if(e[i].cnt==0) id[++m]=e[i].val;
}
sort(a+1,a+n+1,cmp);
sort(id+1,id+m+1,cmp);
for(int i=1,j=1;i<=m;i++)
{
while(id[i]>a[j]&&i<=m) i++;
if(i>m) break;
while(id[i]<a[j]) vis[j]=id[i]+1,j++;
}
int y=0,ans=0;
for(int i=1;i<=n;i++)
{
if(vis[i])
{
int x=vis[i];
while(mp.count(x)&&mp[x]<=0) x++;
ans+=a[i]-x;
if(mp.count(x)) mp[x]--;
}
else
{
while(mp.count(y)&&mp[y]<=0) y++;
ans+=a[i]-y;
if(mp.count(y)) mp[y]--;
}
}
if(ans&1) cout<<"Pico"<<endl;
else cout<<"FuuFuu"<<endl;
}
signed main()
{
//ios;
int T;cin>>T;
while(T--)
solve();
return 0;
}
C. Grass
首先要想到一块草坪若5个点共线肯定不存在,否则就能找到一块符合条件的草坪。因此我们只要固定四个点,去找不共线的第五个点。
对于5个点的判断:方法很多,都很难敲,看到个很巧妙的方法。用set集合,使用最大公约数化成最简形式,观察数量。比我想的一堆垃圾方法好多了。。。
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =3e4+5;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-8;
int n;
struct Point
{
int x,y;
}p[N],P[6];
bool check()
{
for(int i=1;i<=5;i++)
{
set<pair<int,int>>s;
for(int j=1;j<=5;j++)
{
if(j!=i)
{
int x=p[i].x-p[j].x,y=p[i].y-p[j].y;
int tmp=__gcd(x,y);
tmp=abs(tmp);
s.insert({x/tmp,y/tmp});
}
}
if(s.size()==4)
{
P[1]={p[i].x,p[i].y};
int g=1;
for(int j=1;j<=5;j++)
if(j!=i) P[++g]={p[j].x,p[j].y};
return 1;
}
}
return 0;
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>p[i].x>>p[i].y;
int flag=0;
if(n<5)
{
cout<<"NO"<<endl;return;
}
for(int i=5;i<=n;i++)
{
swap(p[i],p[5]);
if(check())
{
flag=1;break;
}
}
if(flag)
{
cout<<"YES"<<endl;
for(int i=1;i<=5;i++)
cout<<P[i].x<<" "<<P[i].y<<endl;
}
else
cout<<"NO"<<endl;
}
signed main()
{
//ios;
int T;cin>>T;
while(T--)
solve();
return 0;
}
C. Complementary XOR
在题数没积累到一定量时,一眼是看不出来的,需要安静下来去分析,浮躁很难做出题来。
思路:
1.如果两个字符串的相同位置既存在值相同的情况,也存在值不同的情况,那么肯定是无解的。
eg: 0 1
—- 1 1
总会存在一个消不去的1。
2.将s1中的1全部化为0,需要g次。若g为偶数,则满足题意;若g为奇数,在最后一个1划掉后,s2全部变为1,进行如下三次操作:对s1的1~n进行翻转,再对1 ~1、2 ~n进行翻转。
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =1e6+5;
const int inf=1e18;
const int mod=998244353;
int n;
string s1,s2;
void solve()
{
cin>>n>>s1>>s2;
s1=" "+s1;s2=" "+s2;
int f1=0,f2=0;
for(int i=1;i<=n;i++)
{
if(s1[i]==s2[i]) f1=1; //各个位置相同
else f2=1; //各个位置不同
}
if(f1&&f2)
{
cout<<"No"<<endl;return;
}
cout<<"Yes"<<endl;
vector<pair<int,int>>e;
int ans=0,g=0;
if(!f1&&f2)
{
ans++;e.push_back({1,n});
for(int i=1;i<=n;i++) s1[i]^=1;
}
for(int i=1;i<=n;i++)
if(s1[i]=='1') ans++,g++,e.push_back({i,i});
if(g%2)
ans+=3,e.push_back({1,n}),e.push_back({1,1}),e.push_back({2,n});
cout<<ans<<endl;
for(auto x:e)
cout<<x.first<<" "<<x.second<<endl;
}
signed main()
{
//ios;
int T;cin>>T;
while(T--)
solve();
return 0;
}
I. Dragon Bloodline
详细注释在代码中,实在是难写。。。。好菜啊好菜
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
using namespace std;
const int N =7e5+5;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-8;
int n,k,a[N],b[105],c[105],f[N],suma=0,sumb=0,sum=0,d[N];
bool check(int x) //二分蛋的数量
{
int kk=0,g=x;
for(int i=1;i<=n;i++)
{
d[i]=a[i]*x; //每种物质需要数量
kk+=d[i];
if(kk>sum) return 0;
}
for(int i=1;i<=k;i++) f[i]=b[i]; //工作的龙数量
for(int i=k;i>=1;i--)
{
sort(d+1,d+n+1); //物质排序、贪心
for(int j=n;j>=1&&f[i]&&d[j];j--)
{
int tmp=d[j]/c[i]; //需要的龙
if(tmp>f[i])
{
d[j]-=c[i]*f[i];f[i]=0;
}
else
{
d[j]-=c[i]*tmp;f[i]-=tmp;
}
}
sort(d+1,d+n+1);
for(int j=n;f[i];j--)
{
if(d[j])
{
d[j]=0;f[i]--;
}
else return 1;
}
}
for(int i=1;i<=n;i++)
if(d[i]) return 0;
return 1;
}
void solve()
{
suma=0,sumb=0,sum=0;
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i],suma+=a[i]; //需要的物质
sort(a+1,a+n+1);
for(int i=1;i<=k;i++) //工作龙
{
cin>>b[i];
sumb+=b[i];
if(i==1) c[i]=1,sum+=c[i]*b[i];
else c[i]=c[i-1]*2,sum+=c[i]*b[i];
}
int l=0,r=sum/suma,mid,ans;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)) l=mid+1,ans=mid;
else r=mid-1;
}
cout<<ans<<endl;
}
signed main()
{
ios;
int T;
cin>>T;
while(T--)
solve();
return 0;
}