每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

AtCoder Beginner Contest 245(D,E,F)

AtCoder Beginner Contest 245(D,E,F)

D (二项式除法)

D

这个题大意就是给你两个二项式A(n)C(n+m),问B(m).其中C(n+m)=A(n)×B(m)

这里的二项式表示方法是这样的,A[i]代表x次数为i的系数

由以上得知,B(m)=C(n+m)A(n)

所以这就是一个经典的二项式除法

推导过程

虽然我不是很明白,具体代码如下

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const double eps=1e-9;
const int maxn=2e5+10;
int n,m;
int a[maxn],b[maxn],c[maxn];
signed main() 
{
   cin>>n>>m;
   for (int i=0;i<=n;i++)
   {
      cin>>a[i];
   }
   for (int i=0;i<=n+m;i++)
   {
      cin>>c[i];
   }
   for (int i=m;i>=0;i--)
   {
      if(c[i+n]==0) b[i]=0;
      else b[i]=c[i+n]/a[n];
      for (int j=0;j<=n;j++)
      {
         c[i+j]-=a[j]*b[i];
      }
   }
   for (int i=0;i<=m;i++)
   {
      cout<<b[i]<<" ";
   }
   system ("pause");
    return 0;
}

E (贪心,二分)

E

这个题的大意是给你n块巧克力,m个盒子,我们要确定这n块巧克力能否安置妥当,也就是放进盒子里,一个盒子只能放一块巧克力,而且这个盒子的长宽都必须大于巧克力的长宽。

我一开始也是想着贪心,把盒子和巧克力都按照从小到大的顺序来,每次选择最前面的那一个盒子,但是我没想到到一点是,我是按照从小到大的x,然后考虑y,我没想到的是假如我的x是满足条件了,但是可能会导致后面有更大的y需要,而我在这里使用了,只因为我是优先考虑x,然后再考虑y

看了题解,下面是我的理解

我们把原来要考虑的有两个,减少到只考虑一个,那就是我们首先按照x大的在前面,然后把还可以使用的放进一个multiset里面,然后对于后面的来说,他们的x都是小于这一个x的,那么我们就可以不用再考虑x了,然后再考虑y,然后我们再贪心的选择大于等于y最小的那一个,可以用lower__bound(这也多亏了multiset会排序,不然还要自己去排序,很麻烦)

然后这里我们是把巧克力和盒子都放进一个数组里面了,优先选择x大的,一样的话,我们先选择盒子,这样后面如果出现巧克力或许可以用得上(这也是我之前没想到过的)

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const double eps=1e-9;
const int maxn=2e5+10;
int n,m;
struct node
{
   int x,y,type;
};
bool cmp(node i,node j)
{
   if(i.x!=j.x)
   {
      return i.x>j.x;
   }
   return i.type>j.type;
}
vector<node>a,res;
signed main() 
{
   cin>>n>>m;
   a.resize(n+m);
   for (int i=0;i<n;i++)
   {
      cin>>a[i].x;
   }
   for (int i=0;i<n;i++)
   {
      cin>>a[i].y;
      a[i].type=0;
   }
   for (int i=0;i<m;i++)
   {
      cin>>a[i+n].x;
   }
   for (int i=0;i<m;i++)
   {
      cin>>a[i+n].y;
      a[i+n].type=1;
   }
   sort(a.begin(),a.end(),cmp);
   bool yes=true;
   multiset<int>st;
   for (int i=0;i<a.size();i++)
   {
      if(a[i].type==1)
      {
         st.insert(a[i].y);
      }
      else 
      {
         int y=a[i].y;
         auto it=st.lower_bound(y);
         if(it==st.end())
         {
            yes=false;
            break;
         }
         else 
         {
            st.erase(it);
         }
      }
   }
   if(yes)
   {
      cout<<"Yes\n";
   }
   else 
   {
      cout<<"No\n";
   }
   system ("pause");
    return 0;
}

F(图,拓扑排序)

F

其实这个题的大意就是给你n个点,m条边,问有多少个点可以进入死循环(也就是环)

一看到这个,我就想到了拓扑排序

对,就是拓扑排序

然后,我们要怎样建图呢

我以前以为正图和反图好像差不多(这一道题我最一开始就是建立了一个正图,虽然样例过了,但是还是错的)

所以我们在建图的时候考虑什么情况是满足要求的

对于这一个题,只有某个点按照正常的图来说,它没有下一个点,即出度为0时,那么它一定不是死循环,刚好对于拓扑排序来时,满足要求的入队,那么我们可以建立一个反向图,这样入度为0的一定是满足条件的

然后就是简单的拓扑排序了

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const double eps=1e-9;
const int maxn=2e5+10;
int n,m;
vector<int>g[maxn];
int in[maxn];
signed main() 
{
   cin>>n>>m;
   for (int i=1;i<=m;i++)
   {
      int u,v;
      cin>>u>>v;
     // g[u].push_back(v);
     // in[v]++;
     g[v].push_back(u);
     in[u]++;
   }
   int ans=n;
   queue<int>q;
   for (int i=1;i<=n;i++)
   {
      if(in[i]==0)
      {
         q.push(i);
         ans--;
      }
   }
   while (!q.empty())
   {
      int u=q.front();
      q.pop();
      for (auto v:g[u])
      {
         in[v]--;
         if(in[v]==0)
         {
            q.push(v);
            ans--;
         }
      }
   }
   cout<<ans<<"\n";
   system ("pause");
    return 0;
}
posted @   righting  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示