Codeforces #566 div2

https://codeforces.com/contest/1182

A.找规律题,偶数输出2^(n/2),奇数0;

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
int main()
{
	int n;
	scanf("%I64d",&n);
	if(n%2==0)
	{   
	long long ans=1;
	for(int i=0;i<n/2;i++)
	{
		ans*=2;
	}
		printf("%I64d",ans);
	}
	else printf("0");
 } 

B题

找到中心的坐标,只能有一个,然后向四周扫就好了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
char mp[550][550];
struct node
{
	int x,y;
}a;
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
	scanf("%s",mp[i]+1);
	bool ok=false;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		if(mp[i][j]=='*'&&mp[i+1][j]=='*'&&mp[i][j+1]=='*'&&mp[i-1][j]=='*'&&mp[i][j-1]=='*')
		{
			if(ok==true)return 0*printf("NO\n");
			ok=true;
			a.x=i,a.y=j;
		}
	}
	mp[a.x][a.y]='.';
    for(int i=a.x-1;i>=1;i--)if(mp[i][a.y]=='*')mp[i][a.y]='.';else break;
    for(int i=a.x+1;i<=n;i++)if(mp[i][a.y]=='*')mp[i][a.y]='.';else break;
    for(int i=a.y-1;i>=1;i--)if(mp[a.x][i]=='*')mp[a.x][i]='.';else break;
    for(int i=a.y+1;i<=m+1;i++)if(mp[a.x][i]=='*')mp[a.x][i]='.';else break;
    for(int i=1;i<=n;i++)
    {
    	for(int j=1;j<=m+1;j++)
    	{
    		if(mp[i][j]=='*')return 0*printf("NO\n");
		}
	}
	if(ok)printf("YES\n");
	else printf("NO\n");
} 

E 矩阵快速幂+费马小定理。

f1,f2,f3的系数满足这个递推式

F(n)=f(n-1)+f(n-2)+f(n-3)

这个递推式用这个矩阵分别对应f1,f2,f3的系数与初始矩阵

\begin{bmatrix} 1 & 1 &1 \\ 1 & 0 &0 \\ 0 &1 &0 \end{bmatrix}\begin{bmatrix} 2\\ 1\\ 1 \end{bmatrix} \begin{bmatrix} 1 & 1 &1 \\ 1 & 0 &0 \\ 0 &1 &0 \end{bmatrix}\begin{bmatrix} 3\\ 2\\ 1 \end{bmatrix} \begin{bmatrix} 1 & 1 &1 \\ 1 & 0 &0 \\ 0 &1 &0 \end{bmatrix}\begin{bmatrix} 4\\ 2\\ 1 \end{bmatrix}

F(n)=f(n-1)+f(n-2)+f(n-3)+2*n-6

这个递推式用

\begin{bmatrix} 1 & 1 & 1 & 1 & 0 \\ 1 & 0 & 0 & 0 &0 \\ \ 0 & 1 &0 & 0 &0 \\ 0 & 0& 0& 1 &2 \\ 0 & 0& 0 & 0& 1 \end{bmatrix} \begin{bmatrix} 0\\ 0\\ 0\\ 2\\ 1 \end{bmatrix}

然后用费马小定理a^(p-1)=1(mod)p;

a^(q)=a^(qmod(p-1)) 这题就出来了。

难度在于第二个非线性的递推式比较难

还有使用离散对数,然后再跑BSGS的方法···学不会

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define up(i,a,n) for(int i=a;i<=n;i++)
#define down(i,a,n) for(int i=a;i>=n;i--)
const int maxn=5;
const int md=1e9+7;
const int md1=1e9+6;
ll n,F1,F2,F3,c; 
struct node
{
	ll a[maxn][maxn];
	friend node operator * (node a,node b)
	{
	node c;
	memset(c.a,0,sizeof(c.a));
	up(i,0,4)
	up(j,0,4)
	up(k,0,4)
	c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%md1)%md1;
	return c;
    }
}unit,unit2;
void init()
{
    unit.a[0][0]=1;unit.a[0][1]=1;unit.a[0][2]=1;
    unit.a[1][0]=1;unit.a[1][1]=0;unit.a[1][2]=0;
    unit.a[2][0]=0;unit.a[2][1]=1;unit.a[2][2]=0;
    unit2.a[0][0] = 1, unit2.a[0][1] = 1, unit2.a[0][2] = 1, unit2.a[0][3] = 1, unit2.a[0][4] = 0;
	unit2.a[1][0] = 1, unit2.a[1][1] = 0, unit2.a[1][2] = 0, unit2.a[1][3] = 0, unit2.a[1][4] = 0;
	unit2.a[2][0] = 0, unit2.a[2][1] = 1, unit2.a[2][2] = 0, unit2.a[2][3] = 0, unit2.a[2][4] = 0;
	unit2.a[3][0] = 0, unit2.a[3][1] = 0, unit2.a[3][2] = 0, unit2.a[3][3] = 1, unit2.a[3][4] = 2;
	unit2.a[4][0] = 0, unit2.a[4][1] = 0, unit2.a[4][2] = 0, unit2.a[4][3] = 0, unit2.a[4][4] = 1;

}
node pow_node(node unit1,ll k)
{  
	node ans,a;
	a=unit1;
	memset(ans.a,0,sizeof(ans.a));
	up(i,0,1)
	ans.a[i][i]=1;
	while(k)
	{
		if(k&1)ans=ans*a;
		k/=2;
		a=a*a;
	}
	return ans;
}
ll pow_num(ll a,ll k)
{
	ll ans=1;
	a%=md;
	while(k)
	{
		if(k&1)ans=((ans%md)*(a%md))%md;
		k/=2;
		a=((a%md)*(a%md))%md;
   }
	return ans;
}
int main()
{  scanf("%I64d %I64d %I64d %I64d %I64d",&n,&F1,&F2,&F3,&c);
   init();
   int f1[3],f2[3],f3[3],f4[5],b,c1,a;
   f1[0]=2,f1[1]=1,f1[2]=1;
   f2[0]=3,f2[1]=2,f2[2]=1;
   f3[0]=4,f3[1]=2,f3[2]=1;
   f4[0]=0,f4[1]=0,f4[2]=0,f4[3]=2,f4[4]=1;
   node res1=pow_node(unit2,n-3);
   long long dd=0;
   for(int i=0;i<5;i++)
   {
   	  dd+=1ll*res1.a[0][i]*f4[i];
   	  dd%=md1;
   }
   long long ans=pow_num(c,dd);
   if(n==4)a=1,b=1,c1=1;
   if(n==5)a=1,b=2,c1=2;
   if(n==6)a=2,b=3,c1=4;
   if(n<=6)
   {
   	ans=(pow_num(c,(n-3)*(n-2))%md*pow_num(F2,b)%md)%md;
   	ans=(ans*pow_num(F1,a)%md)%md;
   	ans=(ans*pow_num(F3,c1)%md)%md;
   	return 0*printf("%I64d\n",ans);
   }
   node res=pow_node(unit,n-6);
   long long aa=0,bb=0,cc=0;
   for(int i=0;i<3;i++)
   {
   	aa+=1ll*res.a[0][i]*f1[i];
   	aa%=md1;
   	bb+=1ll*res.a[0][i]*f2[i];
   	bb%=md1;
	cc+=1ll*res.a[0][i]*f3[i];
   	cc%=md1;
   }
   ans=(ans*pow_num(F1,aa))%md;
   ans=(ans*pow_num(F2,bb))%md;
   ans=(ans*pow_num(F3,cc))%md;
   cout<<ans<<endl; 
}

C题,是一道模拟题···STL大法好,这题需要熟练运用map以及auto的遍历方法了,直接暴力就可以了。

代码注释里面很清楚。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vii vector<pii>
#define vll vector<pll>
const int maxn=1e5+10;
int n;
string s[maxn];
map<int,map<char,vector<int>>>m;
vii pos2;
vii pos1;
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>s[i];
		int cnt=0;
		char last;
		for(int j=0;j<s[i].size();j++)
		{
			if(s[i][j]=='a'||s[i][j]=='e'||s[i][j]=='i'||s[i][j]=='o'||s[i][j]=='u')cnt++,last=s[i][j];
		}
		m[cnt][last].pb(i);
	}
	for(auto &q:m)//此处进入第二个mp auto遍历mp时按第一个关键字遍历。也就是int,元音的个数 
	{
		vector<int>t;
		for(auto &p:q.second)//找到元音个数相同的之后,在进入尾元音相同的 
		{
			auto &k=p.second;//然后遍历里面的位置 
			for(auto i=0;i+1<k.size();i+=2)//开始匹配,末尾元音相同,且元音个数相同 
			{
				pos2.pb({k[i],k[i+1]});
			}
			if((int)k.size()%2)t.pb(k.back());//如果是奇数,就是有落单的,先放进pos1 
		}
		for(auto i=0;i+1<t.size();i+=2)pos1.pb({t[i],t[i+1]}); 
	}
	while((int)pos2.size()>(int)pos1.size())//没有落单的就直接分配就好了 
	{
		pos1.pb(pos2.back());
		pos2.pop_back();
	}
	int num=min((int)pos1.size(),(int)pos2.size());//等于最小的对数 
	cout<<num<<endl;
	for(int i=0;i<num;i++)//输出答案 
	{
		cout<<s[pos1[i].first]<<" "<<s[pos2[i].first]<<endl;
		cout<<s[pos1[i].second]<<" "<<s[pos2[i].second]<<endl;
	}
	return 0;
} 
发布了67 篇原创文章 · 获赞 4 · 访问量 4811

猜你喜欢

转载自blog.csdn.net/weixin_44203780/article/details/91492521