Codeforces Round #338 (Div. 2)

2023-12-22 17:32
文章标签 codeforces round div 338

本文主要是介绍Codeforces Round #338 (Div. 2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接: http://codeforces.com/contest/615

第一题:

很简单

#include<bits/stdc++.h>
using namespace std;
int nn[140];
int main(){int n,m;while(cin>>n>>m){memset(nn,0,sizeof(nn));for(int i = 0;i<n;i++){int a;cin>>a;for(int j = 0;j<a;j++){int b;cin>>b;b--;nn[b] = 1;}}int ans = 0;for(int i = 0;i<m;i++){if(nn[i] == 1)ans++;}if(ans==m)cout<<"YES"<<endl;else cout<<"NO"<<endl;}}

第二题:对于我这种英语渣渣,题意太难理解了。但也不难。

题意:

在一张纸上有一个n个点,m条边的无向图,并且没有指向自己的边。找出一个严格递增的相连的线路,记录这条线路的点数a,并记录这条线路末尾最大的点有几天相邻的边b,求a×b的最大值。

解题思路:

利用动态规划的思想,dp[i] = max(dp[i],dp[j]+1)其中j<i,并且(i,j)相连,这样就求出结尾为i的tail的最大长度。然后它的spines就是与i相连的点的个数。求出两者相乘的最大的值。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100050;
typedef long long ll;
vector<int>V[maxn];
int dp[maxn];
int main(){int n,m;cin>>n>>m;for(int i = 0;i<m;i++){int a,b;cin>>a>>b;V[a].push_back(b);V[b].push_back(a);}memset(dp,0,sizeof(dp));dp[1] = 1;ll ans = 1;for(int i = 1;i<=n;i++){dp[i] = 1;for(int j = 0;j<V[i].size();j++){if(i>V[i][j]){dp[i] = max(dp[i],dp[V[i][j]]+1);}}int t  = V[i].size();//cout<<t<<" "<<dp[i]<<endl;ans = max(ans,1ll*dp[i]*t);}cout<<ans<<endl;}

第三题:这道题进了思想误区,导致比赛结束后wa掉了。

题意:给两个字串a,b。在a或reverse(a)中截取k个字串,让这些字串拼接成b串,求k的最小值,并输出截取字串的起始x和终止位置y。在a中的x<y,在reverse(a)中x>y。如果不能拼接成b,输出-1。


解题思路:

不能拼接成时,为b中包含a中不含有的字母。

能拼接成时

ans = 0
for i in b:ma = 0
    for j in a:cnt = 0;ii = i;jj = j(1)while ii == jj:      (2)ii++;jj++;cnt++  (3)ma = max(ma,cnt)for j  in reverse(a):(1)(2)(3)i+=ma-1;ans++
print ans

ma是一次字串的最大长度,cnt是每次对比的最大长度,ans是字串段数,然后记 录一下jj-ma+1和jj

#include<bits/stdc++.h>
using namespace std;
int aa[27];
int bb[27];
int qi[2500];
int ho[2500];
int main(){string a,ar,b;cin>>a;cin>>b;ar = a;reverse(ar.begin(),ar.end());int al = a.size();int bl = b.size();for(int i = 0;i<al;i++)aa[a[i]-'a'] = 1;for(int i = 0;i<bl;i++)bb[b[i]-'a'] = 1;for(int i  = 0;i<26;i++){if(aa[i]==0&&bb[i]==1){cout<<"-1"<<endl;return 0;}}int ans = 0;for(int i = 0;i<bl;i++){int ma = 0,ma1=  0;for(int j = 0;j<al;j++){int ii = i;int cnt = 0;int yn = 0;int jj = j;while(b[ii] == a[jj]){ii++;jj++;cnt++;if(ii>=bl)break;if(jj>= al)break;yn = 1;}ma1 = max(ma,cnt);if(ma1 !=ma){qi[ans] = jj-ma1+1;ho[ans] = jj;}ma = ma1;}for(int j = 0;j<al;j++){int ii = i;int cnt = 0;int yn = 0;int jj = j;while(b[ii] == ar[jj]){ii++;jj++;cnt++;if(ii>=bl)break;if(jj>= al)break;yn = 1;}ma1 = max(ma,cnt);if(ma1 !=ma){qi[ans] = jj;ho[ans] = jj-ma1+1;}ma = ma1;}i+=ma-1;ans++;}cout<<ans<<endl;for(int i = 0;i<ans;i++){cout<<qi[i]<<" "<<ho[i]<<endl;}return 0;
}

第四题:水平太洼,比赛的时候不会做。

题意:给n各质数,求这n各质数相乘的值m的所有的因子的乘积mod(1e9+7)。例如给出3个质数2,2,3。乘积为12。让求1×2×3×4×6×12mod(1e9+7)的值。

解题思路:

小于200000的素数不是很多,所以肯定有很多重复的数字。开一个map,记录素数和对应的个数。

然后看组合情况,假设素数j有k个,那么j有(kj+1)种出现的形式,所以对于所有的素数就有(k1+1)×(k2+1)×(k3+1)×(k4+1)*...*(kn+1)= sum种组合方式。不考虑j时就有sum/(kj+1)种。假设其中一种除j外的乘积为a,那么就有(a)×(a×j)×(a× j^2)×(a×j^3)×...×(a×j^kj) = (a^(kj+1))×(j^(kj*(kj+1)/2)) .所以在所有的情况中共乘了j^((kj*(kj+1)/2))^(sum/(kj+1)).对于每一个素数求解一遍,乘积mod(1e9+7)为结果。

但是因为数据量过大,会导致sum爆 long long,所以在求解每一个j的sum/(kj+1)时要想办法。

我们用cnt(j)表示j^((kj*(kj+1)/2))

所以我们用d表示遍历到j时的种类的个数,即d(j)= (k1+1)×(k2+1)×(k3+1)×...×(kj+1)

然后

d(0)=1;ans = 1;
for j in ma:cnt(j)ans=ans^(k+1)*cnt(j)^d(j-1);d(j)
ans为最终结果例如我们有一组数据2 2 3 5 5
cnt(1) = 2^(2*3/2)=8,cnt(2)=3^(1+2/2)cnt(3)
j = 1:ans = cnt(1)^1
    d(1)=d(0)*(k1+1)=(k1+1)
j = 2:ans = cnt(1)^1^(k2+1)*cnt(2)^(k1+1)d(2) =d(1)*(k2+1)= (k1+1)*(k2+1)
j = 3:ans = cnt(1)^1^(k2+1)^(k3+1)*cnt(2)^(k1+1)(k3+1)*cnt(3)^(k1+1)*(k2+1)d(3) = d(2)*(k3+1)

并且在本解法中没有sum/k的运算。由费马小定理若p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p),则a^x≡a^(x%(m-1))(mod p)
所以再加上%mod得到:
d(0)=1;ans = 1;
for j in ma:cnt(j)ans=ans^(k+1)%mod*cnt(j)^d(j-1)%mod;d(j)%(mod-1)
然后再用快速幂解法
ll fast_mod(ll n,ll m,ll mod){ll ans =1;while(m){if(m&1)ans = ans*n%mod;m>>=1;n = n*n%mod;}return ans;
}

即可快速的求解出ans。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p[200050];
map<int ,ll>MA;
const ll mod = 1e9+7;
ll fast_mod(ll n,ll m,ll mod){ll ans =1;while(m){if(m&1)ans = ans*n%mod;m>>=1;n = n*n%mod;}return ans;
}
int main(){int T;cin>>T;MA.clear();for(int i = 0;i<T;i++){int a;scanf("%d",&a);MA[a]++;}map<int,ll>::iterator it;ll sum = 1;ll ans = 1;for(it = MA.begin();it!=MA.end();it++){int cnt = fast_mod(it->first,(it->second+1)*it->second/2,mod);ans=fast_mod(ans,it->second+1,mod)*fast_mod(cnt,sum,mod)%mod;sum=sum*(it->second+1)%(mod-1);}printf("%I64d\n",ans);
}

第五题:找公式??

题解:

我们根据例子发现,每往外一层增加6步,所以我们可以求出给出步数k的层数nn。

然后我们发现每一层有六条边,每一条边的步数为层数nn。

我们可以求出要求步数k的层数nn,边数bian,还有在该边的第几步ge。

然后根据坐标求解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){ll n;cin>>n;if(n == 0){cout<<"0 0"<<endl;return 0;}//int x,int y;//cout<<"n"<<n<<endl;ll nn =(n+5)/6;ll ns = sqrt(nn*2);while(ns*(ns+1)/2<nn)ns++;ns--;
//cout<<ns<<endl;//完整的层数ll cnt,bian,ge;cnt = n-ns*(ns+1)/2*6-1;bian = cnt/(ns+1);ge = cnt%(ns+1);ll cx,cy;ll x,y;ge++;ns++;if(bian == 0){cx = 2*ns;cy = 0;x = cx-ge;y = cy+ge*2;}if(bian == 1){cx = ns,cy =2*ns;x = cx-ge*2;y = cy;}if(bian == 2){cx = -ns,cy =2*ns;x = cx-ge;y = cy-ge*2;}if(bian == 3){cx = -ns*2,cy =0;x = cx+ge;y = cy-ge*2;}if(bian == 4){cx = -ns,cy =-2*ns;x = cx+ge*2;y = cy;}if(bian == 5){cx = ns,cy =-2*ns;x = cx+ge;y = cy+ge*2;}cout<<x<<" "<<y<<endl;
}




















这篇关于Codeforces Round #338 (Div. 2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/524840

相关文章

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor

创建一个大的DIV,里面的包含两个DIV是可以自由移动

创建一个大的DIV,里面的包含两个DIV是可以自由移动 <body>         <div style="position: relative; background:#DDF8CF;line-height: 50px"> <div style="text-align: center; width: 100%;padding-top: 0px;"><h3>定&nbsp;位&nbsp;

Codeforces Round 971 (Div. 4) (A~G1)

A、B题太简单,不做解释 C 对于 x y 两个方向,每一个方向至少需要 x / k 向上取整的步数,取最大值。 由于 x 方向先移动,假如 x 方向需要的步数多于 y 方向的步数,那么最后 y 方向的那一步就不需要了,答案减 1 代码 #include <iostream>#include <algorithm>#include <vector>#include <string>

CF#271 (Div. 2) D.(dp)

D. Flowers time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/474/problem/D We s

CF #278 (Div. 2) B.(暴力枚举+推导公式+数学构造)

B. Candy Boxes time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/488/problem/B There