10.16考试总结

来源:互联网 发布:http的默认端口 编辑:程序博客网 时间:2024/06/01 20:56

首先为什么最近疯狂写总结呢,当然是教练要求啊,不能只顾埋头刷题,边捡边掉可不划算。

1. 匹配(100/100)

    题目大意:有一些等个数的黑白点,现在把它们配成一个个点对,定义点距为曼哈顿距离,白点恒在黑点右下。求最小距离和。

       感想:看了一眼,咦,这不是一个定值吗,直接加加减减就出来了嘛,然后就开始怀疑人生了,z这么简单?excuse me'?普及组?然后半个小时过去,还是没想到更“科学”的做法,然后打了上去,然后A了。。。。。

# include <iostream># include <cstdio># include <cstring># include <queue># include <cmath># include <stack># include <algorithm>using namespace std;typedef long long ll;ll Read(){ll i=0,f=1;char c=getchar();while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}return i*f;}ll n,a,b,x,y,x2,y2;int main(){n=Read();for(int i=1;i<=n;++i){a=Read(),b=Read();x+=a,y+=b;}for(int i=1;i<=n;++i){a=Read(),b=Read();x2+=a,y2+=b;}printf("%I64d\n",(x2-x)+(y-y2));}
2.玩积木(0/100)

    题目大意:给一个什么东西:0

                                                        1  1

                                                        2   2   2

                                                        3   3   3   3

                                                        4   4   4   4   4 

                                                        5   5   5   5   5   5

    现在把它打乱,现在只能动0,且只能向其左上方,上方,右下方,下方,求最少需要多少次数还原(规定不会超过20次);

    感想:看一眼,搜索?,那应该是暴力把,想了半天,还是觉得是搜索,于是我开始怀疑人生了,半个小时后,突发奇想会不会是dp,于是开始想转移状态,想不出来,最后直接暴力都不想打了,直接交了个随机输出,果不其然0分。正解:搜索!a*,折半都可以,反正直接搜就对了。。。

# include <iostream># include <cstdio># include <cstring># include <queue># include <cmath># include <stack># include <algorithm>using namespace std;int Read(){int i=0,f=1;char c=getchar();while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}return i*f;}const int INF=1e9+7;const int Map[7][7]={0,0,0,0,0,0,0,                     0,0,0,0,0,0,0,                     0,1,1,0,0,0,0,     0,2,2,2,0,0,0,     0,3,3,3,3,0,0,     0,4,4,4,4,4,0,     0,5,5,5,5,5,5};struct node{int x,y;node(){}node(int x,int y) : x(x),y(y){}};int n,m,t,ans,a[10][10];bool vis[10][10]={false};node go(node p,int i){if(i==1) p.x--;if(i==2) p.x--,p.y--;if(i==3) p.x++;if(i==4) p.x++,p.y++;return p;}inline int judge(){int num=0;for(int i=1;i<=6;++i)    for(int j=1;j<=i;++j)        if(a[i][j]!=Map[i][j]) num++;     return num;}inline void DFS(node p,int dep){if(dep>ans) return ;if(judge()==0) {ans=min(ans,dep);return;}if(dep+judge()>ans) return;for(int i=1;i<=4;++i){node now=go(p,i);if(now.x>=1&&now.x<=6&&now.y>=1&&now.y<=now.x&&a[now.x][now.y]){swap(a[p.x][p.y],a[now.x][now.y]);DFS(now,dep+1);swap(a[p.x][p.y],a[now.x][now.y]);}}}int main(){t=Read();while(t--){node pos;ans=21;for(int i=1;i<=6;++i)    for(int j=1;j<=i;++j)    {    a[i][j]=Read();    if(a[i][j]==0) pos=node(i,j);    }memset(vis,0,sizeof(vis));DFS(pos,0);if(ans!=21) printf("%d\n",ans);else printf("too difficult\n");}}
3.字符串(30/100)

    题意:给许多字符串,再与一个字符串s匹配,看看有多少组匹配,m次操作修改s中的一个字符,再次匹配;

    感想:因为前两题的怀疑人生,做这道题只剩半小时了,于是打了个kmp拿了30分走人。正解:ac自动机,每次修改只会影响位置前后最长字符串长度的位置,每次只匹配now-maxlen,now+maxlen,于是ok。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>using namespace std;int getint() {    int i=0,f=1;char c;    for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());    if(c=='-')c=getchar(),f=-1;    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';    return i*f;}int buf[1024];inline void W(int x){if(!x){putchar('0');return ;}if(x<0){putchar('-');x=-x;}while(x) buf[++buf[0]]=x%10,x/=10;while(buf[0]) putchar(buf[buf[0]--]+48);return ;}const int N=1005;const int M=1e5+5;const int L=105;struct node{int cnt,fail,son[26];}tr[N*L];char s[M];int tot,n,m,mx;void insert(){int len=strlen(s),po=1;mx=max(mx,len);for(int i=0;i<len;i++){if(!tr[po].son[s[i]-'a'])tr[po].son[s[i]-'a']=++tot;po=tr[po].son[s[i]-'a'];}tr[po].cnt++;}void buildfail(){int head=0,tail=1;static int que[N*L];que[tail]=1;while(head<tail){head++;int u=que[head],v,w;for(int i=0;i<26;i++){v=tr[u].fail;while(!tr[v].son[i])v=tr[v].fail;v=tr[v].son[i],w=tr[u].son[i];if(w)tr[w].fail=v,que[++tail]=w,tr[w].cnt+=tr[v].cnt;else tr[u].son[i]=v;}}}int ac_auto(int l,int r){int po=1,ans=0,tmp;for(int i=l;i<=r;i++){po=tr[po].son[s[i]-'a'];ans+=tr[po].cnt;}return ans;}int main(){int pos;char c;tot=1;for(int i=0;i<26;i++)tr[0].son[i]=1;n=getint(),m=getint();while(n--)scanf("%s",s),insert();buildfail();scanf("%s",s);int len=strlen(s);int ans=ac_auto(0,len-1);W(ans),putchar('\n');while(m--){pos=getint();pos--;for(c=getchar();c<'a'||c>'z';c=getchar());int l=max(0,pos-mx),r=min(len-1,pos+mx);ans-=ac_auto(l,r);s[pos]=c;ans+=ac_auto(l,r);W(ans),putchar('\n');}return 0;}

总结:这天我各种怀疑人生,受不了了,希望noip应该不会这么鬼畜。