2017省夏令营final

题解:我们记b、c数组分别表示左右、上下的移动,左-右+,上+下-,如果某2点b、c分别相等,即回到了原地,ans++即可。

对于最后的20%数据,只有左右,我们记录b出现的次数cnt,算出有多少个点在移动过程中走到了相同的位置,ans+=cnt*(cnt-1)/2即可。

PS:①这题虽然相当裸,但是最后一个点爆int,所以我们要开long long存QAQ;②初始的位置0也要考虑。

代码如下:

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #define Max 400005
 4 using namespace std;
 5 long long n,b[Max],c[Max],cnt1[Max],cnt2[Max],ans;
 6 char a[Max];
 7 bool flag;
 8 void work(int x){
 9     if(x>=0) cnt1[x]++;
10     else cnt2[-x]++;
11 }
12 int main()
13 {
14     freopen("command.in","r",stdin);
15     freopen("command.out","w",stdout);
16     scanf("%lld\n",&n); cnt1[0]++;
17     for(int i=1;i<=n;i++){
18         scanf("%c",&a[i]);
19         b[i]=b[i-1]; c[i]=c[i-1];
20         if(a[i]=='U') c[i]++,flag=true;
21         if(a[i]=='D') c[i]--,flag=true;
22         if(a[i]=='L') b[i]--,work(b[i]);
23         if(a[i]=='R') b[i]++,work(b[i]);
24     }
25     if(!flag){
26         for(int i=0;i<=n;i++){
27             ans+=cnt1[i]*(cnt1[i]-1)/2;
28             ans+=cnt2[i]*(cnt2[i]-1)/2;
29         }
30         printf("%lld",ans);
31         return 0;
32     }
33     for(int i=0;i<n;i++)
34         for(int j=i+1;j<=n;j++)
35             if(b[i]==b[j]&&c[i]==c[j]) ans++;
36     printf("%lld",ans);
37     return 0;
38 }

 

------------------------------------------------------------华丽的分割线----------------------------------------------------------------------

 

题解:由题意,我们把相互指向的桌子连起来,就是一张由数个环组成的有向图,我们就可以预处理出每个点所在环的长度xh,搜索时把距离模xh再搜即可。

代码如下:

 1 #include<cstdio>
 2 #include<iostream>
 3 #define Max 100005
 4 using namespace std;
 5 int n,Q,a[Max],b[Max];
 6 int now[Max],to[Max],xh[Max],cnt;
 7 bool vis[Max];
 8 void dfs(int x){
 9     if(vis[x]) return;
10     vis[x]=true; cnt++;
11     dfs(to[x]);
12     xh[x]=cnt;
13 }
14 int find(int x,int y){
15     if(y==0) return x;
16     return find(to[x],y-1);
17 }
18 int main()
19 {
20     freopen("position.in","r",stdin);
21     freopen("position.out","w",stdout);
22     scanf("%d%d",&n,&Q);
23     for(int i=1;i<=n;i++){
24         scanf("%d%d",&a[i],&b[i]);
25         now[a[i]]=i;
26     }
27     for(int i=1;i<=n;i++) to[i]=now[b[i]];
28     for(int i=1;i<=n;i++)
29         if(!vis[i]){cnt=0; dfs(i);}
30     for(int i=1;i<=Q;i++){
31         int x,y; scanf("%d%d",&x,&y);
32         y%=xh[x];
33         printf("%d\n",find(x,y));
34     }
35     return 0;
36 }

 

posted @ 2017-07-27 14:11  Beginner_llg  阅读(118)  评论(0编辑  收藏  举报