http://uoj.ac/contest/53/standings
签了一个A,然后就就结束了。全靠队友,又会玩魔塔,又会matlab又会猜原根。。。。
div2 C题难度的DP,去年银川网络赛第二场抄的很久以前的cf的原题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=210+10;
int n,cas,ans;
int dp[maxl][6];
char s[maxl],a[6];
inline void prework()
{
scanf("%s",s+1);
n=strlen(s+1);
a[1]=a[2]=a[3]='x';
a[4]=a[5]='l';
}
inline void mainwork()
{
for(int i=0;i<=n;i++)
for(int j=0;j<=5;j++)
dp[i][j]=101;
dp[0][0]=0;
for(int i=1;i<=n;i++)
if(s[i]=='x')
{
dp[i][0]=dp[i-1][0]+1;
dp[i][1]=min(dp[i-1][0],dp[i-1][1]+1);
dp[i][2]=min(dp[i-1][1],dp[i-1][2]+1);
dp[i][3]=min(dp[i-1][2],dp[i-1][3]);
dp[i][4]=dp[i-1][4];
}
else
{
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1];
dp[i][2]=dp[i-1][2];
dp[i][3]=dp[i-1][3]+1;
dp[i][4]=min(dp[i-1][3],dp[i-1][4]+1);
}
ans=101;
for(int i=0;i<=4;i++)
ans=min(dp[n][i],ans);
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}
B图片解密
数学院的队友会用matlab,然而我啥可视化都不会。。。
set1直接10不同色缩小就好了
set2
通过新加坡那个钟,
发现86400=24*60*60,然后就只要看时针和分针组成的图案就行了
C魔塔
队友玩出来了。。我玩了一个小时没玩出来。。。一开始发现第一个问号钥匙颜色总是一样的,以为问号颜色不变。。。标了张表格后发现有一些问号颜色会变。。。吐了
队友说“这题区域赛金牌起步的sam,然而在这里被当签到题20分钟就被人切了”
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
int T[N][30],fa[N],len[N],cnt,last,pos[N];
void build(int v){
int i,p=last,np,q,nq;
last=np=++cnt;
len[np]=len[p]+1;
for(;p&&T[p][v]==0;p=fa[p]) T[p][v]=np;
if(p==0) fa[np]=1;
else{
q=T[p][v];
if(len[q]==len[p]+1) fa[np]=q;
else{
nq=++cnt;
len[nq]=len[p]+1;
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for(i=0;i<27;i++) T[nq][i]=T[q][i];
for(;T[p][v]==q;p=fa[p]) T[p][v]=nq;
}
}
}
char s[1000010];
long long sum[1000010][30];
vector<int>g[N];
void dfs(int u,int f){
int i,v;
for(i=0;i<g[u].size();i++){
v=g[u][i];
if(v!=f){
dfs(v,u);
pos[u]=max(pos[v],pos[u]);
}
}
}
int main(){
long long l,r,f,i,j,n,a,b;
scanf("%s",s+1);
n=strlen(s+1);
last=cnt=1;
for(i=1;i<=n;i++){
build(s[i]-'a');
pos[last]=i;
for(j=0;j<=26;j++) sum[i][j]=sum[i-1][j];
sum[i][s[i]-'a']++;
}
for(i=1;i<=cnt;i++) g[fa[i]].push_back(i);
dfs(1,0);
long long ans=0;
for(i=2;i<=cnt;i++){
l=pos[i]-len[i]+1;
r=pos[i]-len[fa[i]];
a=l;
b=len[i]-len[fa[i]];
ans+=(a+a+b-1)*b/2; //?
for(j=0;j<=26;j++){
a=sum[r][j]-sum[l-1][j];
if(a==0) continue;
b=sum[l-1][j];
if(s[r]-'a'==j){
ans-=(b+b+a)*(a-1)/2;
if(fa[i]!=1) ans-=a+b;
}
else ans-=(b+1+b+a)*a/2;
}
}
cout<<ans+1<<endl;
}
队友说这是个质数应该要用到原根,然后突然就过了?(流下了不会数学的泪水)
#include<bits/stdc++.h>
using namespace std;
bool ck(int x,int mod){
int ans=x*x%mod,k=2;
while(ans!=1)ans=ans*x%mod,k++;
return k==mod-1;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
int p=n+1,g=0;
for(int i=2;i<p;i++){
if(ck(i,p)){
g=i;
break;
}
}
if(g==0){printf("-1\n");break;}
int j=1;
for(int i=1;i<p;i++){
printf("%d %d\n",i,j);
j=j*g%p;
}
}
}
这题先把1放在中间,然后维护一个从前到后的顺序,然后二分去确定每一个进来的数应该放在哪一个前面
每次询问就A[0]=i,A[1]=a[mid],如果a[mid]在i后面,则get_lcs=2,否则=1
刚好100*log约等于65
#include "lcs.h"
#include<bits/stdc++.h>
using namespace std;
void find_permutation(int n, int res[])
{
vector<int>k;
int A[3];
k.push_back(1);
int l=0,r=0,mid=0;
for(int i=2;i<=n;i++){
l=0,r=k.size()-1;
while(l<=r){
mid=l+r>>1;
A[0]=k[mid],A[1]=i;
if(get_lcs(2,A)==1)r=mid-1;
else l=mid+1;
}
if(l>mid)k.insert(k.begin()+mid+1,i);
else k.insert(k.begin()+mid,i);
}
for(int i=0;i<n;i++)res[i]=k[i];
}
N热身题
我数独也不会玩,太菜了,还好队友前一天晚上玩出来了
7 1 3 4 8 6 2 9 5
2 4 9 3 5 7 8 6 1
8 5 6 2 1 9 4 7 3
6 7 5 9 4 8 1 3 2
4 2 8 7 3 1 9 5 6
3 9 1 6 2 5 7 8 4
1 8 2 5 9 3 6 4 7
9 3 7 1 6 4 5 2 8
5 6 4 8 7 2 3 1 9