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的系数满足这个递推式
这个递推式用这个矩阵分别对应f1,f2,f3的系数与初始矩阵
这个递推式用
然后用费马小定理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;
}