第五周 9.28---10.4

---------9.28

 新的一周  >_<

 

下午的cf又滚粗了---

不过总比上次爆零好----好忧桑啊--------

 

cf 581 C

http://codeforces.com/contest/581/problem/C

比赛的时候一直在纠结这两种情况,然后一直贪不出来,然后,居然还去想dp了,,,挫爆

纠结的是这种

37  19  ,k = 3

这种是应该给 37呢,还是给19,然后一直在想要怎么去判断一下怎么加更优-----

其实不用想那么多---sad----

因为每个数的值最多只能够加到100,所以它每次加到整十的收益就是 1,花费就是 10 - a[i] %10

然后像这个例子,就变成 20  39,就好了

然后算每个数最多能够变成多大,统计一下答案就可以了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 //wei ziji jiayou >_<99
 9 
10 const int maxn = 100005;
11 int a[maxn];
12 int n,k;
13 
14 int cmp(int a,int b){
15     return a%10 > b%10;
16 }
17 
18 void solve(){
19     sort(a+1,a+n+1,cmp);
20 //    for(int i = 1;i <= n;i++) printf("%d ",a[i]);
21 //    printf("\n");
22     
23     for(int i = 1;i <= n;i++){
24         int tmp = 10 - (a[i]%10);
25         if(tmp < 10 && tmp <= k){
26             a[i] += tmp;
27             k -= tmp;
28         }
29     }
30     
31     int res = 0;
32     for(int i = 1;i <= n;i++){
33         int tmp = 100-a[i];
34         if(tmp <= k){
35             a[i] += tmp;
36             k -= tmp;
37         }
38         else{
39             a[i] += k;
40             k = 0;
41         }
42         res += a[i]/10;
43     }
44     printf("%d\n",res);
45 }
46 
47 int main(){
48     while(scanf("%d %d",&n,&k) != EOF){
49         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
50         solve();
51     }
52     return 0;
53 }
View Code


cf 581 d

http://codeforces.com/problemset/problem/581/D

给出三个矩形,问能不能够构成一个正方形

又sad了---

比赛的时候想着怎样去把一个正方形分割成三个矩形,然后去枚举切割位置

情况好多---没有写---

后来这样写的,但是还是感觉有点麻烦

先扫出边界上的矩形,确定下正方形的边长,然后枚举剩下的两个矩形的各种拼接方式,看满不满足

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

char g[105];
char res[105][105];

struct node{
    int x,y;
}a[5];

int x2,y2,x3,y3,x1,y1;
int flag;

void work(int x2,int y2,int x3,int y3,char c1,char c2){
//    printf("x2 = %d  y2 = %d  x3 = %d  y3 = %d  c1 = %c  c2 = %c\n",x2,y2,x3,y3,c1,c2);
    if((y3 == y2) && (y3 + x1) == y1 && (x2 + x3) == y1){
        flag = 1;
        for(int i = 1;i <= x2;i++){
            for(int j = x1+1;j <= y1;j++) res[i][j] = c1;
        }
        for(int i = x2+1;i <= y1;i++){
            for(int j = x1+1;j <= y1;j++) res[i][j] = c2;
        }
    }
    
    if((y2 == y3) && (y2 == y1) && (x1 + x2 + x3) == y1){
        flag = 1;
        for(int i = 1;i <= y1;i++){
            for(int j = x1 +1;j <= x1+x2;j++) res[i][j] = c1;
        }
        for(int i = 1;i <= y1;i++){
            for(int j = x1+x2+1;j <= y1;j++) res[i][j] = c2;
        }
    }
}

void print(){
    printf("%d\n",y1);
    for(int i = 1;i <= y1;i++){
        for(int j = 1;j <= y1;j++) printf("%c",res[i][j]);
        printf("\n");
    }
    printf("\n");
}

void solve(){
    g[1] = 'A'; g[2] = 'B'; g[3] = 'C';
    int maxx = -1;
    for(int i = 1;i <= 3;i++) {
        maxx = max(maxx,a[i].x);
        maxx = max(maxx,a[i].y);
    }

    int pos = 0;
    for(int i = 1;i <= 3;i++){
        if(a[i].x == maxx || a[i].y == maxx){
            pos = i;
            break;
        }
    }
    if(a[pos].x > a[pos].y) swap(a[pos].x,a[pos].y);
    
    x1 = a[pos].x; y1 = a[pos].y;
//    printf("x1 = %d  y1 = %d\n",x1,y1);
    
    for(int i = 1;i <= y1;i++){
        for(int j = 1;j <= x1;j++) res[i][j] = g[pos];
    }
//    print();
    
    int ok = 0;
    char c1,c2;
    for(int i = 1;i <= 3;i++){
        if(i != pos && ok == 0) {
            x2 = a[i].x;
            y2 = a[i].y;
            c1 = g[i];
            ok = 1;
        } 
        if(i != pos && ok){
            x3 = a[i].x;
            y3 = a[i].y;
            c2 = g[i];
        }
    }
    flag = 0;
    work(x2,y2,x3,y3,c1,c2);
    if(flag) {
        print();
        return;
    }
    work(x2,y2,y3,x3,c1,c2);
    if(flag) {
        print();
        return;
    }
    work(y2,x2,x3,y3,c1,c2);
    if(flag) {
        print();
        return;
    }
    work(y2,x2,y3,x3,c1,c2);
    if(flag) {
        print();
        return;
    }
    puts("-1");
}

int main(){
    while(scanf("%d %d %d %d %d %d",&a[1].x,&a[1].y,&a[2].x,&a[2].y,&a[3].x,&a[3].y) != EOF){
        solve();
    }
    return 0;
}
View Code

 

没事---下次接着加油----gooooooooooo

 

---------9.29

cf 501 C

http://codeforces.com/contest/501/problem/C

给出一个森林中每一个节点的度数,以及和它临接的节点的异或和

输出这个森林里面所有的边

先一直没有推出来是,那个邻接的异或和没有搞清楚,是所有的邻接的顶点的异或和

然后就从叶子节点开始找,叶子节点的异或和,就是这条边的另一端,然后就一层一层这样找下去

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<queue>
 7 using namespace std;
 8 
 9 const int maxn = 1000005;
10 typedef pair<int,int> pii;
11 
12 int d[maxn],x[maxn];
13 int n;
14 
15 void solve(){
16     queue<int> q;
17     vector<pii> res;
18     for(int i = 0; i < n;i++) if(d[i] == 1) q.push(i);
19     
20     while(!q.empty()){
21         int u = q.front();q.pop();
22         if(d[u] == 0) continue;
23     //    printf("d[%d] = %d  x[%d] = %d\n",u,d[u],u,x[u]);
24         
25         d[u]--;
26         int v = x[u];
27         res.push_back(make_pair(u,v));
28         x[v] = x[v]^u;
29         d[v]--;
30         if(d[v] == 1) q.push(v);
31     }
32     printf("%d\n",res.size());
33     for(int i = 0;i < res.size();i++){
34         printf("%d %d\n",res[i].first,res[i].second);
35     }
36 }
37 
38 int main(){
39     while(scanf("%d",&n) != EOF){
40         memset(d,0,sizeof(d));
41         memset(x,0,sizeof(x));
42         for(int i = 0;i < n;i++){
43             scanf("%d %d",&d[i],&x[i]);
44         }
45         solve();
46     }
47     return 0;
48 }
View Code

 

hdu 5489

给出一列数,删除连续的k个数之后,求最长的LIS的长度

比赛的时候,一直想的是拼接的办法,就是枚举切割的点,然后将两段的LIS加起来,维持一个最大值

可是,这样不对,因为不能够保证这两段能不能够拼接起来

后来看题解---

还是分成两段的办法

假设当前的位置是 i,i位置对应的值为 v,离散化后对应的值为y

然后建立一颗线段树

每次查询[0,y-1] 对应的最大dp值(这样就可以保证两段可以拼接起来),加上以i为起点的最长LIS的长度

再维持一个最大值

最后还要和不拼接的两种情况比较一下,就是删去最前面一段,和删去最后面一段

 

-----觉得线段树写得太少了,,,改了好久的说,离散化写得也好挫,,看别人的写的几十行就写完了-------

没事-----------------加油 ---->_<

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 
  8 #define getmid(l,r)  l + (r-l)/2
  9 
 10 // wei ziji  jiayou >_<
 11 
 12 const int maxn = 100005;
 13 const int INF = (1<<30)-1;
 14 int g[maxn],a[maxn],L[maxn],R[maxn];
 15 int n,k;
 16 int b[maxn];
 17 int nmax;
 18 
 19 struct Node{
 20     int x,id;
 21 }p[maxn];
 22 
 23 struct node{
 24     int l,r,maxx;
 25 }t[4*maxn];
 26 
 27 int cmp(Node n1,Node n2){
 28     return n1.x < n2.x;
 29 }
 30 int cmp1(Node n1,Node n2){
 31     return n1.id < n2.id;
 32 }
 33 
 34 void init() {
 35     for(int i = 1; i <= n; i++) g[i] = INF;
 36     for(int i = 1; i <= n; i++) {
 37         int k = lower_bound(g+1, g+1+n, a[i]) - g;
 38         L[i] = k;
 39         g[k] = a[i];
 40     }
 41     for(int i = 1; i <= n; i++) a[i] = -a[i];
 42     for(int i = 1; i <= n; i++) g[i] = INF;
 43     for(int i = n; i > 0; i--) {
 44         int k = lower_bound(g+1, g+1+n, a[i]) - g;
 45         R[i] = k;
 46         g[k] = a[i];
 47     }
 48 }
 49 
 50 void Push_up(int p){
 51     t[p].maxx = max(t[p<<1].maxx,t[p<<1|1].maxx);
 52 }
 53 
 54 void Build_tree(int p,int l,int r){
 55     t[p].l = l;
 56     t[p].r = r;
 57     if(l == r){
 58         t[p].maxx = 0;
 59         return;
 60     }
 61     int mid = getmid(l,r);
 62     Build_tree(p<<1,l,mid);
 63     Build_tree(p<<1|1,mid+1,r);
 64     Push_up(p);
 65 }
 66 
 67 void Update(int p,int s,int w){
 68     if(t[p].l == t[p].r){
 69         t[p].maxx = w;
 70         return;
 71     }
 72     int mid = getmid(t[p].l,t[p].r);
 73     if(s <= mid) Update(p<<1,s,w);
 74     else Update(p<<1|1,s,w);
 75     Push_up(p);
 76 }
 77 
 78 void query(int p,int l,int r){
 79     if(t[p].maxx <= nmax) return;
 80     if(t[p].l == l && t[p].r == r){
 81         nmax = max(t[p].maxx,nmax);
 82         return;
 83     }
 84     int mid = getmid(t[p].l,t[p].r);
 85     if(r <= mid) query(p<<1,l,r);
 86     else if(l > mid) query(p<<1|1,l,r);
 87     else {
 88         query(p<<1,l,mid);
 89         query(p<<1|1,mid+1,r);
 90     }
 91 }
 92 
 93 void solve(){    
 94     memset(L,0,sizeof(L));
 95     memset(R,0,sizeof(R));
 96     init();
 97     for(int i = 1;i <= n;i++) p[i].id = i, p[i].x = -a[i];
 98     sort(p+1,p+n+1,cmp);
 99     for(int i = 1,j = 0;i <= n;i++){
100         if(i == 1 || p[i].x != p[i-1].x) j++;
101         b[p[i].id] = j;
102     }
103     
104     Build_tree(1,1,n);
105     
106     sort(p+1,p+n+1,cmp1);
107     int res = 0;
108     for(int i = k+1;i <= n;i++){
109         int pos = b[p[i].id];
110         nmax = 0;
111         if(pos-1 >  0) query(1,1,pos-1);
112         
113         int tmp = nmax;
114         
115         res = max(res,tmp+R[i]);
116         int pos1 = b[p[i-k].id];
117         
118     //    printf("i = %d  pos = %d  tmp = %d  pos1 = %d\n",i,pos,tmp,pos1);
119         Update(1,pos1,L[i-k]);
120     }
121 //    printf("res = %d\n",res);
122     res = max(res,max(L[n-k],R[k+1]));
123     printf("%d\n",res);
124 }
125 
126 int main(){
127     int T;
128     scanf("%d",&T);
129     int kase = 0;
130     while(T--){
131         scanf("%d %d",&n,&k);
132         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
133         printf("Case #%d: ",++kase);
134         solve();
135     }
136     return 0;
137 }
View Code

 

hdu 5475

感觉思路好巧妙啊----,把除法的转化成乘法了

如果操作是1的话,就把a[i]更新成为要乘的那个数

如果操作是2的话,就把a[a[i]]更新成1

然后询问就是输出区间1到i的乘积,这会儿再取模

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 //wei ziji jiayou >_<
 9 
10 #define getmid(l,r) l +(r-l)/2
11 
12 typedef long long LL;
13 const int maxn = 100005;
14 int a[maxn];
15 int n,m;
16 LL ans[maxn];
17 
18 struct node{
19     int l,r;
20     LL c;
21 }t[4*maxn];
22 
23 void Push_up(int p){
24     t[p].c = t[p<<1].c * t[p<<1|1].c % m;
25 }
26 
27 void Build_tree(int p,int l,int r){
28     t[p].l = l;
29     t[p].r = r;
30     if(l == r){
31         t[p].c = 1;
32         return;
33     }
34     int mid = getmid(l,r);
35     Build_tree(p<<1,l,mid);
36     Build_tree(p<<1|1,mid+1,r);
37     Push_up(p);
38 }
39 
40 void Update(int p,int s,int w){
41     if(t[p].l == t[p].r ){
42         t[p].c = w;
43         return;
44     }
45     int mid = getmid(t[p].l,t[p].r);
46     if(s <= mid) Update(p<<1,s,w);
47     else Update(p<<1|1,s,w);
48     Push_up(p);
49 }
50 
51 LL Query(int p,int l,int r){
52     if(t[p].l == l && t[p].r == r){
53         return t[p].c;
54     }
55     int mid = getmid(t[p].l,t[p].r);
56     if(r <= mid) return Query(p<<1,l,r);
57     else if(l > mid) return Query(p<<1|1,l,r);
58     else return Query(p<<1,l,mid) * Query(p<<1|1,mid+1,r) %m;
59 }
60 
61 void solve(){
62     Build_tree(1,1,n);
63 //    for(int i = 1;i <= 2*n;i++) printf("t[%d].c = %I64d  l = %d  r = %d\n",i,t[i].c,t[i].l,t[i].r);
64     memset(ans,0,sizeof(ans));
65     for(int i = 1;i <= n;i++){
66             int op;
67             scanf("%d %d",&op,&a[i]);
68             if(op == 1) Update(1,i,a[i]);
69             else Update(1,a[i],1);
70             LL res = Query(1,1,i) % m;
71         //    printf("%I64d\n",res);
72         ans[i] = res;
73     }
74     for(int i = 1;i <= n;i++) printf("%I64d\n",ans[i]);
75 }
76 
77 int main(){
78     int T;
79     scanf("%d",&T);
80     int kase = 0;
81     while(T--){
82         scanf("%d %d",&n,&m);    
83         printf("Case #%d:\n",++kase);
84         solve();
85     }
86     return 0;
87 }
View Code

 

cf 522 a

http://codeforces.com/problemset/problem/522/A

DAG上的最长路

定义成 string s1

然后写的时候直接用的s1[i],会RE,,,,不懂用stirng,还是改成char 了----

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<map>
 6 #include<vector>
 7 using namespace std;
 8 
 9 map<string,int> c;
10 const int maxn = 5005;
11 int dp[maxn];
12 int n,m;
13 char s1[105],s2[105],s3[105];
14 int len1,len3;
15 vector<int> g[maxn];
16 
17 void changes1(){
18     for(int i = 0;i < len1;i++){
19         if(s1[i] >= 'A' && s1[i] <= 'Z') s1[i] = s1[i]-'A'+'a';
20     }
21 }
22 
23 void changes3(){
24     for(int i = 0;i < len3;i++){
25         if(s3[i] >= 'A' && s3[i] <= 'Z') s3[i] = s3[i]-'A'+'a';
26     }
27 }
28 
29 void dfs(int u){
30     dp[u] = 1;
31     for(int i = 0;i < g[u].size();i++){
32         int v = g[u][i];
33         dfs(v);
34         dp[u] = dp[v] + 1;
35     }
36 }
37 
38 void solve(){
39     int cnt = 0;
40     memset(dp,0,sizeof(dp));
41     for(int i = 1;i <= maxn;i++) g[i].clear();
42     for(int i = 1;i <= n;i++){
43         cin >> s1 >> s2 >> s3;
44         len1 = strlen(s1);
45         len3 = strlen(s3);
46     //    printf("s1 = %s  s2 = %s  s3 = %s\n",s1.c_str(),s2.c_str(),s3.c_str());
47         changes1();
48         changes3();
49         if(c.count(s1) == 0) c[s1] = ++cnt;
50         if(c.count(s3) == 0) c[s3] = ++cnt;
51         int u = c[s1], v = c[s3];
52         g[u].push_back(v); 
53     //    printf("i = %d  u = %d  v = %d\n",i,u,v);
54     }
55 //    for(int i = 1;i <= cnt;i++){
56 //        printf("i = %d  ",i);
57 //        for(int j = 0;j < g[i].size();j++){
58 //            int v = g[i][j];
59 //            printf("%d ",v);
60 //        }
61 //        printf("\n");
62 //    }
63     
64     int res = -1;
65     for(int i = 1;i <= cnt;i++) dfs(i);
66     for(int i = 1;i <= cnt;i++) res = max(res,dp[i]);
67     printf("%d\n",res);
68 }
69 
70 int main(){
71     scanf("%d",&n);
72     solve();
73     return 0;
74 }
View Code

 

---------9.30

cf 234 C

http://codeforces.com/problemset/problem/234/C

改变最少的数,使得这列数的前面一段为负数,后面一段为正数

递推求出负数和零的个数,然后枚举一下断开的点

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 100005;
 8 int a[maxn],sum[maxn],ling[maxn];
 9 int n;
10 
11 void solve(){
12     memset(sum,0,sizeof(sum));
13     memset(ling,0,sizeof(ling));
14     int c = 0;
15     
16     if(n == 2){
17         int res = 0;
18         if(a[1] >= 0) res++;
19         if(a[2] <= 0) res++;
20         printf("%d\n",res);
21         return;
22     }
23     
24     for(int i = 1;i <= n;i++){
25         if(a[i] < 0) sum[i] = sum[i-1]+1;
26         else sum[i] = sum[i-1];
27         
28         if(a[i] == 0) ling[i] = ling[i-1]+1,c++;
29         else ling[i] = ling[i-1];
30     }
31     
32     //for(int i = 1;i <= n;i++) printf("sum[%d] = %d  ling[%d] = %d\n",i,sum[i],i,ling[i]);
33     
34     int res = (1<<30)-1;
35     for(int i = 2;i <= n-1;i++){
36         int l =(i-1)-sum[i-1] -ling[i-1];//suan zhengshu
37         int r = sum[n]-sum[i];//suan fushu
38         res = min(res,l+r);
39     //    printf("i = %d  l = %d  r = %d\n",i,l,r);
40     }
41     printf("%d\n",res+c);
42 }
43 
44 int main(){
45     freopen("input.txt","r",stdin);
46     freopen("output.txt","w",stdout);
47     while(scanf("%d",&n) != EOF){
48         memset(a,0,sizeof(a));
49         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
50         solve();
51     }
52     return 0;
53 }
View Code

 

cf 219 C

http://codeforces.com/problemset/problem/219/C

给出k个不同的字母,再给出一个字符串

替换最少的字母,使得这个字符串里面相邻的两个字母都不相同

先贪错了,,,顺着扫一遍,再逆着扫一遍--这样不对

应该从k的个数来考虑

如果 k == 2,就只能够是 ABABABA,BABABAB这两种情况,判断一下哪种更少就可以了

如果 k >= 3,所以相邻的相同的一定可以找到第三个来和它们不一样,直接扫一遍就可以了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 //wei ziji jiayou >_<
 9 
10 const int maxn = 500005;
11 char s[maxn],t[maxn],e[maxn];
12 int n,k;
13 
14 void solve(){
15     if(k == 2){
16         int c1 = 0,c2 = 0;
17         for(int i = 1;i <= n;i++){
18             if(i%2 == 1) t[i] = 'A';
19             else t[i] = 'B';
20             if(s[i] != t[i]) c1++;
21         }
22         
23         for(int i = 1;i <= n;i++){
24             if(i%2 == 1) e[i] = 'B';
25             else e[i] = 'A';
26             if(s[i] != e[i]) c2++;
27         }
28         printf("%d\n",min(c1,c2));
29         if(c1 <= c2) printf("%s\n",t+1);
30         else printf("%s\n",e+1);
31         return;
32     }
33     
34     int c = 0;
35     for(int i = 2;i <= n;i++){
36         if(s[i] == s[i-1]){
37             for(int j = 1;j <= k;j++){
38                 int u = s[i]-'A'+1;
39                 int v = s[i+1]-'A'+1;
40                 if(j != u && j != v){
41                     s[i] = j+'A'-1;
42                     c++;
43                     break;
44                 }
45             }
46         }
47     }
48     printf("%d\n",c);
49     printf("%s\n",s+1);
50 }
51 
52 int main(){
53     while(scanf("%d %d",&n,&k) != EOF){
54         scanf("%s",s+1);
55         solve();
56     }
57     return 0;
58 }
View Code

 

cf 407 b

http://codeforces.com/contest/407/problem/B

给出n个房间,给出pi

如果是第奇数次走到这个房间,那么接下来他就去到pi

如果是第偶数次走到这个房间,那么接下来他就去到i+1

问从第1间房间到达第n+1间房间至少需要走多少步

被绕晕了-----

用cnt[i]记录下来,第一次到i  ------到兜完一圈再次到达i需要的步数

cnt[i] = sigma cnt[k]  + i-pi +1,pi <= k < i

这个画下图,推下样例可以得到

然后dp[i] = dp[i-1] + cnt[i] + 1

然后求的就是dp[n+1],

其实还是不太懂,画画图,凑了凑样例,凑的---

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 
 8 const int mod = 1e9+7;
 9 const int maxn = 100005;
10 int dp[maxn],cnt[maxn];
11 int n,p[maxn];
12 
13 void solve(){
14     memset(dp,0,sizeof(dp));
15     memset(cnt,0,sizeof(cnt));
16     
17     for(int i = 1;i <= n;i++){
18         for(int j = p[i];j < i;j++) cnt[i] = (cnt[i] + cnt[j]) % mod;
19         
20         cnt[i] = (cnt[i] + i-p[i]+1)%mod;
21     //    printf("cnt[%d] = %d\n",i,cnt[i]);
22     }
23     
24     for(int i = 2;i <= n+1;i++){
25         dp[i] = (dp[i-1] + cnt[i-1] + 1)%mod;
26     //    printf("dp[%d] = %d\n",i,dp[i]);
27     }
28     printf("%d\n",dp[n+1]);
29 }
30 
31 int main(){
32     while(scanf("%d",&n) != EOF){
33         memset(p,0,sizeof(p));
34         for(int i = 1;i <= n;i++) scanf("%d",&p[i]);
35         
36         solve();
37     }
38     return 0;
39 }
View Code

 

---------10.1

弱校联萌第一天-

 

---------10.2

弱校联萌第二天

 

---------10.3

弱校联萌第一天 J  Right turn

http://www.bnuoj.com/v3/contest_show.php?cid=6865#problem/J

一神教的办法>_<

先记录下方向,然后暴力找到最近的障碍物,如果有就转弯,如果没有,就直接出去了

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 
  8 const int maxn = 1005;
  9 int n;
 10 const int INF = (1<<30)-1;
 11 
 12 struct node{
 13     int x,y;
 14 }a[maxn];
 15 
 16 void solve(){
 17     int sx,sy,nx,ny;
 18     int res = 0;
 19     int ok = 0;
 20     sx = 0;sy = 0;
 21     for(;;){
 22         for(int i = 0;i < 4;i++){
 23         if(i == 0){
 24             nx = INF;
 25             ok = 0;
 26             for(int j = 1;j <= n;j++){
 27                 if(a[j].y == sy){
 28                     if(a[j].x > sx){
 29                         nx = min(a[j].x,nx);
 30                         ok = 1;
 31                     }
 32                 }
 33             }
 34             sx = nx-1; 
 35         }
 36         
 37         if(i == 3){
 38             ny = INF;
 39             ok = 0;
 40             for(int j = 1;j <= n;j++){
 41                 if(a[j].x == sx){
 42                     if(a[j].y > sy){
 43                         ny = min(ny,a[j].y);
 44                         ok = 1;
 45                     }
 46                 }
 47             }
 48             sy = ny-1;
 49         }
 50         if(i == 2){
 51             nx = -INF;
 52             ok = 0;
 53             for(int j = 1;j <= n;j++){
 54                 if(a[j].y == sy){
 55                     if(a[j].x < sx){
 56                         nx = max(a[j].x,nx);
 57                         ok = 1;
 58                     }
 59                 }
 60             }
 61             sx = nx+1;
 62         }
 63         if(i == 1){
 64             ny = -INF;
 65             ok = 0;
 66             for(int j = 1;j <= n;j++){
 67                 if(a[j].x == sx){
 68                     if(a[j].y < sy){
 69                         ny = max(ny,a[j].y);
 70                         ok = 1;
 71                     }
 72                 }
 73             }
 74             sy = ny+1;
 75         }
 76         
 77         //printf("i = %d  sx = %d  sy = %d\n",i,sx,sy);
 78         
 79         if(ok == 0){
 80             printf("%d\n",res);
 81             return;
 82         }
 83         else res++;
 84         
 85         if(res > 5000){
 86             puts("-1");
 87             return;
 88         }
 89     }
 90     }
 91 }
 92 
 93 int main(){
 94     while(scanf("%d",&n) != EOF){
 95         for(int i = 1;i <= n;i++){
 96             scanf("%d %d",&a[i].x,&a[i].y);
 97         }
 98         solve();
 99     }
100     return 0;
101 }
View Code

 

弱校联萌第一天 B Carries

http://www.bnuoj.com/v3/contest_show.php?cid=6865#problem/B

把所有的个位,十位,百位,-----,千万位分别放进一个vector,排序后,再挨次找能够让它进位的数有多少个

终于知道wa了一天哪儿错了-----555555555555555

10^9是9个0,不是8个0------------要找到亿位-------

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 
  8 typedef long long LL;
  9 const int maxn = 100005;
 10 vector<int> b[15];
 11 int n;
 12 int a[maxn];
 13 int c[15][maxn];
 14 
 15 int ge(int x){
 16     return x%10;
 17 }
 18 
 19 int sh(int x){
 20     return (x/10%10)*10 + ge(x);
 21 }
 22 
 23 int ba(int x){
 24     return (x/100%10)*100 + sh(x);
 25 }
 26 
 27 int qi(int x){
 28     return (x/1000%10)*1000+ba(x);
 29 }
 30 
 31 int wa(int x){
 32     return (x/10000%10)*10000 + qi(x);
 33 }
 34 
 35 int sw(int x){
 36     return (x/100000%10)*100000 + wa(x); 
 37 }
 38 
 39 int bw(int x){
 40     return (x/1000000%10)*1000000 + sw(x);
 41 }
 42 
 43 int qw(int x){
 44     return (x/10000000%10)*10000000+bw(x);
 45 }
 46 
 47 int yi(int x){
 48     return (x/100000000%10)*100000000+qw(x);
 49 }
 50 
 51 void work(int x){
 52     b[1].push_back(ge(x));
 53     b[2].push_back(sh(x));
 54     b[3].push_back(ba(x));
 55     b[4].push_back(qi(x));
 56     b[5].push_back(wa(x));
 57     b[6].push_back(sw(x));
 58     b[7].push_back(bw(x));
 59     b[8].push_back(qw(x)); 
 60     b[9].push_back(yi(x));
 61 }
 62 
 63 void solve(){
 64     memset(c,0,sizeof(c));
 65     for(int i = 1;i <= 10;i++) b[i].clear();
 66     
 67     for(int i = 1;i <= n;i++) work(a[i]);
 68     for(int i = 1;i <= 9;i++) sort(b[i].begin(),b[i].end());
 69     
 70     for(int i = 1;i <= 9;i++){
 71         for(int j = 0;j < b[i].size();j++) {
 72             c[i][j] = b[i][j];
 73             //printf("%d ",b[i][j]);
 74         }
 75        // printf("\n");
 76     }
 77     
 78     LL res = 0;
 79     for(int i = 1;i <= 9;i++){
 80         for(int j = 0;j < b[i].size();j++){
 81             int tmp;
 82             int x;
 83             if(i == 1)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),10-ge(b[i][j]))-c[i],x = 10-ge(b[i][j]);
 84             if(i == 2)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),100-sh(b[i][j]))-c[i],x = 100-sh(b[i][j]);
 85             if(i == 3)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),1000-ba(b[i][j]))-c[i],x = 1000-ba(b[i][j]);
 86             if(i == 4)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),10000-qi(b[i][j]))-c[i],x = 10000-qi(b[i][j]);
 87             if(i == 5)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),100000-wa(b[i][j]))-c[i],x = 100000-wa(b[i][j]);
 88             if(i == 6)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),1000000-sw(b[i][j]))-c[i],x = 1000000-sw(b[i][j]);
 89             if(i == 7)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),10000000-bw(b[i][j]))-c[i],x = 10000000- bw(b[i][j]);
 90             if(i == 8)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),100000000-qw(b[i][j]))-c[i],x = 100000000-qw(b[i][j]);
 91             if(i == 9)tmp = lower_bound(c[i]+j,c[i]+b[i].size(),1000000000-yi(b[i][j]))-c[i],x = 1000000000-yi(b[i][j]);
 92             int l = 0;
 93             if(tmp == j) l = b[i].size()-tmp-1;
 94             else {
 95                 if(tmp == b[i].size()) l = 0;
 96                 else l = b[i].size()-tmp;
 97             }
 98             
 99             //printf("i = %d  tmp = %d l = %d x = %d\n",i,tmp,l,x);
100             res += 1LL*l;
101         }
102         //printf("\n\n");
103     }
104     printf("%lld\n",res);
105 }
106 
107 int main(){
108     while(scanf("%d",&n) != EOF){
109         memset(a,0,sizeof(a));    
110             
111         for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
112         solve();
113     }
114     return 0;
115 }
View Code

 

转载于:https://www.cnblogs.com/wuyuewoniu/p/4843210.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值