1599 逆向bfs+优化
#include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<string> using namespace std; int a,b,c,d; bool _find(int u,int v){ while(1){ if(u==0||v==0) return false;//试一下分母为0的话会怎么样 if(u<a&&v<b) return false; if(u<b&&v<a) return false; if(u<v){ u^=v; v^=u; u^=v; } if(v==a&&u>=b&&(u-b)%v==0) return true; if(v==b&&u>=a&&(u-a)%v==0) return true; int tmp=u%v; u=v;v=tmp; } } int main() { int T,i; scanf("%d",&T); while(T--){ scanf("%d%d%d%d",&a,&b,&c,&d); if(_find(c,d)) printf("YES\n"); else printf("NO\n"); } return 0; }
1601 DP
hiho1601 #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<memory> #include<cstring> using namespace std; const int maxn=1010; long long a[maxn],b[maxn],c[maxn]; long long dp[maxn][maxn],Max; int main() { long long n,i,j,k,m,cnt=0; scanf("%lld%lld",&n,&m); for(i=1;i<=n;i++) scanf("%lld",&a[i]); sort(a+1,a+n+1); for(i=1;i<=n;i++){ if(a[i]!=a[i-1]) { b[++cnt]=a[i]; c[cnt]=1; } else c[cnt]++; } memset(dp,-1,sizeof(dp)); for(i=0;i<=cnt;i++) dp[i][0]=0; dp[1][1]=b[1]*c[1]; Max=dp[1][1]; for(i=2;i<=cnt;i++) for(j=1;j<=m;j++){ dp[i][j]=dp[i-1][j]; if(b[i]-b[i-1]>1) dp[i][j]=max(dp[i][j],dp[i-1][j-1]+b[i]*c[i]); else dp[i][j]=max(dp[i][j],dp[i-2][j-1]+b[i]*c[i]); Max=max(Max,dp[i][j]); } printf("%lld\n",Max); return 0; }
1602 manacher+bkdrhash
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<map> using namespace std; #define ULL unsigned long long const int maxn=2000000+20; ULL P = 1313131; ULL sqr[maxn/2],has[maxn/2],V[maxn]; int Laxt[maxn],Next[maxn],cnt=0; const int MOD = 2000007; bool _insert(ULL Now) { int u=Now%MOD; for(int i=Laxt[u];i;i=Next[i]){ if(V[i]==Now) return true; } Next[++cnt]=Laxt[u]; Laxt[u]=cnt; V[cnt]=Now; return false; } int ans=0; map<ULL, int> mp; void _hash(int x,int y){ ULL Now=has[y]-has[x-1]*sqr[y-x+1]; if(!_insert(Now)) ++ans,mp[Now]++; } void _malacher() { int R=0,Mid=0,Len; char c[maxn]; scanf("%s",c+1); Len=strlen(c+1); sqr[0]=1; for(int i=1;i<=Len;i++){ sqr[i]=sqr[i-1]*P; has[i]=has[i-1]*P+c[i]; } int r[maxn]; for(int i=1;i<=Len;++i) { _hash(i,i); if(R>i) r[i]=min(r[2*Mid-i],R-i); while(i+r[i]+1<=Len&&c[i+r[i]+1]==c[i-r[i]-1]){ _hash(i-r[i]-1,i+r[i]+1); r[i]++; } if(i+r[i]>R) { R=i+r[i]; Mid=i; } } cnt=0;Mid=0;R=0; memset(Laxt,0,sizeof(Laxt)); memset(r,0,sizeof(r)); for(int i=2;i<=Len;++i) { if(R>i) r[i]=min(r[2*Mid-i],R-i+1); while(i+r[i]<=Len&&c[i+r[i]]==c[i-r[i]-1]) { _hash(i-r[i]-1,i+r[i]); ++r[i]; } if(i+r[i]-1>R) { R=i+r[i]-1; Mid=i; } } printf("%d\n",ans); } int main() { _malacher(); return 0; }
1603 暴力
1603 #include<cstdio> #include<cstdlib> #include<iostream> #include<cstring> #include<algorithm> #include<memory> using namespace std; char c[1000]; int main() { int i=1,j,L,a,b; int num=0; gets(c+1); L=strlen(c+1); for(;;) { bool flag=false; for(;i<=L;i++) if(c[i]=='@'){ flag=true; a=i+1; break; } if(!flag) break; for(;i<=L;) { if(c[i+1]>='a'&&c[i+1]<='z') i++; else { b=i; break; } } if(b-a>=0) { if(num) printf(" "); for(j=a;j<=b;j++) printf("%c",c[j]); num++; } i++; if(i>L) break; } printf("\n"); return 0; } //丑代码
1604 BIT最区间最大,再找剩余区间的峰值直到结束
1604 #include<cstdio> #include<cstdlib> #include<iostream> #include<memory> #include<algorithm> using namespace std; const int maxn=1000000+10; int a[maxn],n; int Max[maxn]; int pos[maxn]; int sum[maxn]; int _lowbit(int x) { return x&(-x); } void _add(int p,int num) { int tmp=p; while(tmp<=n){ if(Max[tmp]<num){ pos[tmp]=p; Max[tmp]=num; } tmp+=_lowbit(tmp); } } int _get(int x,int y) { int tmp=0,p; while(x<=y){ if(y-_lowbit(y)>=x){ if(Max[y]>tmp){ tmp=Max[y]; p=pos[y]; } y-=_lowbit(y); } else { if(a[y]>tmp){ tmp=a[y]; p=y; } y--; } } return p; } int main() { int i,j,k,L,R,ans=0; scanf("%d",&n); L=1;R=n; for(i=1;i<=n;i++) { scanf("%d",&a[i]); _add(i,a[i]); sum[i]=sum[i-1]+a[i]; } while(L<R){ k=_get(L,R); ans=ans-(sum[k]-sum[L-1])+(k-L+1)*a[k]; L=k+1; } printf("%d\n",ans); return 0; }
1605 斐波那契 数列的偶数项
1606 看不懂题,ORZ
1607 双指针或者二分?前缀和? 都可以反正就是尽量用乘法避免除法带来的精度误差
1607 #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cstring> using namespace std; int a[100010]; long long ans; int main() { int n,i,j,L,R; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); L=1;R=1;//L是左可行,R是右可行 for(i=1;i<=n;i++){ while((a[L]-8)*8<a[i]&&L<n) L++; if(a[i]<88888) while(a[R]<=88888&&R<=n&&(a[R]<=8*a[i]+8)) R++; else while(a[R]<=8*a[i]+8&&R<=n) R++; ans+=(R-L); if(i>=L&&i<R) ans--; } printf("%lld\n",ans); return 0; }
1608 DP
#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define ll long long int n,m,k; char s[303][303]; int dp[5050][15]; int dis[303][303]; int d[15][15]; int x[15],y[15]; int a[4][2]={0,1,1,0,0,-1,-1,0}; queue<pair<int,int> >q; void bfs(int sx,int sy) { int i; dis[sx][sy]=0; while(!q.empty())q.pop(); q.push(make_pair(sx,sy)); while(!q.empty()) { pair<int,int>tmp=q.front();q.pop(); int x=tmp.first,y=tmp.second; for(i=0;i<4;i++) { int xx=x+a[i][0],yy=y+a[i][1]; if(xx<0||xx>=n||yy<0||yy>=m||s[xx][yy]=='1') continue; if(dis[xx][yy]==-1) { dis[xx][yy]=dis[x][y]+1; q.push(make_pair(xx,yy)); } } } } int main() { int i,j; scanf("%d%d%d",&n,&m,&k); for(i=0;i<n;i++) scanf("%s",s[i]); for(i=1;i<=k;i++)scanf("%d%d",x+i,y+i); x[0]=0,y[0]=0,x[++k]=n-1,y[k]=m-1; for(i=0;i<=k;i++){ memset(dis,-1,sizeof(dis)); bfs(x[i],y[i]); for(j=0;j<=k;j++) d[i][j]=dis[x[j]][y[j]]; } memset(dp,-1,sizeof(dp)); dp[0][0]=0; for(int i=0;i<(1<<(k+1));i++) for(int j=0;j<=k;j++)//两个for顺序不能反 if(dp[i][j]!=-1) { for(int q=0;q<=k;q++) { int ret=i|(1<<q); if(d[j][q]!=-1&&(dp[ret][q]==-1||dp[ret][q]>dp[i][j]+d[j][q])) dp[ret][q]=dp[i][j]+d[j][q]; } } printf("%d\n",dp[(1<<(k+1))-1][k] ); return 0; }
1611 拓扑排序
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1010;
const int maxm=1000010;
double x[maxn],y[maxn],r[maxn];
int Laxt[maxn],Next[maxm],To[maxm];
int In[maxn],fa[maxn];
int n,cnt;
void _add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
In[v]++;
}
int main()
{
int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%lf%lf%lf",&x[i],&y[i],&r[i]);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++){
if(i==j) continue;
double d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
if(d+r[i]<=r[j]) _add(j,i);
if(d+r[j]<=r[i]) _add(i,j);
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++)
if(In[j]==0) {
for(k=Laxt[j];k;k=Next[k]){
fa[To[k]]=j;
In[To[k]]--;
}
In[j]--;
break;
}
}
for(i=1;i<=n;i++)
printf("%d\n",fa[i]);
return 0;
}
1612 乱搞但是未果
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=400000;
int h[maxn],w[maxn],num[maxn];
int Max,Min;
struct in
{
int c;
int t;
}p[maxn];
int cmp(in a,in b){
return a.t<b.t;
}
int main()
{
int n,m,i,j,k,ans=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d%d",&p[i].t,&p[i].c);
}
for(i=1;i<=m;i++){
scanf("%d",&j);
w[j]=1;
}
sort(p+1,p+n+1,cmp);
h[0]=m;Max=0;Min=0;
for(i=1;i<n;i++){
num[p[i].c]++;
if(w[p[i].c]){
if(Min==num[p[i].c]-1&&h[num[p[i].c]-1]==1) Min++;
h[num[p[i].c]-1]--;
h[num[p[i].c]]++;
}
else Max=max(Max,num[p[i].c]);
if(Min>Max) ans=ans+p[i+1].t-p[i].t;
}
printf("%d\n",ans);
return 0;
}