zoukankan      html  css  js  c++  java
  • matrix_last_acm_1

    password 123

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/A

    题意:n个数初始ai,m次操作,查询某个点的值,或者区间加上一个数,对于加的操作,是区间中的每一个元素下标i的倍数 i 2i 3i 。。。都加上这个数。

    解法:先预处理出n个下标的所有因子,加的操作只加区间内的,就是一倍的地方。所以对于加操作就是正常的区间加上一个值,对于查询,就需要把这个下标的因子的值都加上。需要输入挂,树状数组。树状数组处理区间加,单点查,【x,y】+=z  在【x】 +z  在【y+1】 -z,最后单点查询就是查询前n项和。

      1 //#define debug
      2 //#define txtout
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<cctype>
      8 #include<ctime>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<queue>
     13 #include<stack>
     14 #include<map>
     15 #include<set>
     16 #define mt(a,b) memset(a,b,sizeof(a))
     17 using namespace std;
     18 typedef long long LL;
     19 const double eps=1e-8;
     20 const double pi=acos(-1.0);
     21 const int inf=0x3f3f3f3f;
     22 const int M=3e5+10;
     23 int a[M];
     24 int n,m;
     25 struct G {
     26     int op,x,y,z;
     27     LL ans;
     28 } g[M];
     29 vector<int> fac[M];
     30 int length[M];
     31 class One_Tree_Array { ///一维树状数组
     32     static const int M=3e5+10; ///点的个数
     33     typedef LL typev;
     34     typev a[M];
     35     int n;
     36 public:
     37     void init(int tn) { ///传入点数,点下标1 开始
     38         n=tn;
     39         for(int i=0; i<=n; i++) a[i]=0;
     40     }
     41     int lowb(int t) {
     42         return t&(-t);
     43     }
     44     void add(int i,typev v) {
     45         for(; i<=n; a[i]+=v,i+=lowb(i));
     46     }
     47     typev sum(int i) {
     48         typev s=0;
     49         for(; i>0; s+=a[i],i-=lowb(i));
     50         return s;
     51     }
     52 } gx;
     53 void init() {
     54     for(int i=1; i<M; i++) {
     55         fac[i].clear();
     56     }
     57     for(int i=1; i<M; i++) {
     58         for(int j=i; j<M; j+=i) {
     59             fac[j].push_back(i);
     60         }
     61     }
     62     for(int i=1; i<M; i++) {
     63         length[i]=fac[i].size();
     64     }
     65 }
     66 void solve() {
     67     gx.init(n);
     68     for(int i=0; i<m; i++) {
     69         if(g[i].op&1) {
     70             g[i].ans=a[g[i].x];
     71             for(int j=0; j<length[g[i].x]; j++) {
     72                 g[i].ans+=gx.sum(fac[g[i].x][j]);
     73             }
     74             continue;
     75         }
     76         gx.add(g[i].x,g[i].z);
     77         gx.add(g[i].y+1,-g[i].z);
     78     }
     79 }
     80 int getint() {
     81     int res=0;
     82     char tmp;
     83     while(!isdigit(tmp=getchar()));
     84     do {
     85         res=(res<<3)+(res<<1)+tmp-'0';
     86     } while(isdigit(tmp=getchar()));
     87     return res;
     88 }
     89 int main() {
     90 #ifdef txtout
     91     freopen("in.txt","r",stdin);
     92     freopen("out.txt","w",stdout);
     93 #endif
     94     init();
     95     n=getint();
     96     for(int i=1; i<=n; i++) {
     97         a[i]=getint();
     98     }
     99     m=getint();
    100     for(int i=0; i<m; i++) {
    101         g[i].op=getint();
    102         g[i].x=getint();
    103         if(g[i].op&1) continue;
    104         g[i].y=getint();
    105         g[i].z=getint();
    106     }
    107     solve();
    108     for(int i=0; i<m; i++) {
    109         if(g[i].op&1) {
    110             printf("%lld
    ",g[i].ans);
    111         }
    112     }
    113     return 0;
    114 }
    View Code

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/C

    题意:有n颗树,每颗树高度ti,每棵树有一只猴子,每秒往上爬一步,ti步到达顶后,每秒往下走一步,到底又开始往上爬,查询任意时刻所有猴子最高的位置。

    解法:正解不知道,暴力的话对每个查询遍历所有的树,算出猴子所在高度去最大值,n*m。但是我只测了最高的两个树就ac了。。。样例太水了?还是正解就是如此?有待讨论。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const int inf=0x3f3f3f3f;
    22 const int M=1e6+10;
    23 int a[M];
    24 int b[M];
    25 int n,m;
    26 int get_value(int h,int t) {
    27     t%=(2*h);
    28     if(t<=h) return t;
    29     t-=h;
    30     return h-t;
    31 }
    32 void solve() {
    33     sort(a,a+n);
    34     n=unique(a,a+n)-a;
    35     int from=max(0,n-2);
    36     for(int i=0; i<m; i++) {
    37         if(b[i]<=a[n-1]) continue;
    38         int ans=0;
    39         for(int j=from; j<n; j++) {
    40             ans=max(ans,get_value(a[j],b[i]));
    41         }
    42         b[i]=ans;
    43     }
    44 }
    45 int getint() {
    46     int res=0;
    47     char tmp;
    48     while(!isdigit(tmp=getchar()));
    49     do {
    50         res=(res<<3)+(res<<1)+tmp-'0';
    51     } while(isdigit(tmp=getchar()));
    52     return res;
    53 }
    54 int main() {
    55 #ifdef txtout
    56     freopen("in.txt","r",stdin);
    57     freopen("out.txt","w",stdout);
    58 #endif
    59     n=getint();
    60     for(int i=0; i<n; i++) {
    61         a[i]=getint();
    62     }
    63     m=getint();
    64     for(int i=0; i<m; i++) {
    65         b[i]=getint();
    66     }
    67     solve();
    68     for(int i=0; i<m; i++) {
    69         printf("%d
    ",b[i]);
    70     }
    71     return 0;
    72 }
    View Code

    D http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/D

    题意:构造一个长度为n的整数数组,使得数组中数的种类至少k种,且任意一个子串的和的种类最少。

    解法:用k-1种数,其他全为0,然后前k-1种数一正一负且绝对值相等,例如1 -1 2 -1 3 -3...这样可以使得子串种类尽量少。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const int inf=0x3f3f3f3f;
    22 const int M=1e3+10;
    23 int n,k;
    24 int a[M];
    25 void solve(){
    26     int now=1;
    27     int la=0;
    28     for(int i=0;i<n;i++){
    29         a[i]=0;
    30     }
    31     for(int i=0;i<k-1;i+=2){
    32         a[la++]=now;
    33         if(i+1>=k-1) break;
    34         a[la++]=-now;
    35         now++;
    36     }
    37 }
    38 int main(){
    39     #ifdef txtout
    40     freopen("in.txt","r",stdin);
    41     freopen("out.txt","w",stdout);
    42     #endif
    43     while(~scanf("%d%d",&n,&k)){
    44         solve();
    45         for(int i=0;i<n;i++){
    46             printf("%d%c",a[i],i==n-1?'
    ':' ');
    47         }
    48     }
    49     return 0;
    50 }
    View Code

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/E

    题意:给abc三个数,之间有两个符号,+-*,问可得到最小值。

    解法:枚举3*3=9种情况。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const int inf=0x3f3f3f3f;
    22 const int M=1e5+10;
    23 int a,b,c;
    24 int solve(){
    25     int res=inf;
    26     res=min(res,a+b+c);
    27     res=min(res,a+b-c);
    28     res=min(res,a+b*c);
    29     res=min(res,a-b+c);
    30     res=min(res,a-b-c);
    31     res=min(res,a-b*c);
    32     res=min(res,a*b+c);
    33     res=min(res,a*b-c);
    34     res=min(res,a*b*c);
    35     return res;
    36 }
    37 int main(){
    38     #ifdef txtout
    39     freopen("in.txt","r",stdin);
    40     freopen("out.txt","w",stdout);
    41     #endif
    42     while(~scanf("%d%d%d",&a,&b,&c)){
    43         printf("%d
    ",solve());
    44     }
    45     return 0;
    46 }
    View Code

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/F

    题意:定义p(u,v)为u,v两点距离,定义p(u,v,w)= pvu) + pvw) + puw),求多少对uv满足v ≠ u 并且pvu) ≥ pvuw) 对于所有的 w。

    解法:根据要求可以发现,必须是所有点都共线,且最两端的点,才能满足恰好相等,可以由三角形两边和大于第三边证明。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const int inf=0x3f3f3f3f;
    22 const int M=2e5+10;
    23 struct point{
    24     LL x,y;
    25     int pid;
    26     friend bool operator <(const point &a,const point &b){
    27         return a.x<b.x||(a.x==b.x&&a.y<b.y);
    28     }
    29 }p[M];
    30 int n;
    31 LL xmult(point p1,point p2,point p0){ ///计算向量叉积(P1-P0)x(P2-P0)
    32     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    33 }
    34 bool not_on_line(){
    35     for(int i=2;i<n;i++){
    36         if(xmult(p[0],p[1],p[i])) return true;
    37     }
    38     return false;
    39 }
    40 int main(){
    41     #ifdef txtout
    42     freopen("in.txt","r",stdin);
    43     freopen("out.txt","w",stdout);
    44     #endif
    45     while(~scanf("%d",&n)){
    46         for(int i=0;i<n;i++){
    47             scanf("%lld%lld",&p[i].x,&p[i].y);
    48             p[i].pid=i+1;
    49         }
    50         if(not_on_line()){
    51             puts("0");
    52             continue;
    53         }
    54         puts("1");
    55         sort(p,p+n);
    56         printf("%d %d
    ",p[0].pid,p[n-1].pid);
    57     }
    58     return 0;
    59 }
    View Code

    G http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/G

    题意:给n堆石头,每堆都是奇数个,D和S轮流玩,D先玩,每次玩家可以选一堆石头,将其分为3堆且每堆都是奇数,最后谁没法分就输。

    解法:发现一堆 a 个石头能被分 a/2 向下取整次。统计一下能分的次数的奇偶就知道胜负。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const int inf=0x3f3f3f3f;
    22 const int M=1e3+10;
    23 int a[M];
    24 int n;
    25 char str[][32]={"Daenerys","Stannis"};
    26 int solve(){
    27     int res=0;
    28     for(int i=0;i<n;i++){
    29         res+=a[i]/2;
    30     }
    31     return res&1^1;
    32 }
    33 int main(){
    34     #ifdef txtout
    35     freopen("in.txt","r",stdin);
    36     freopen("out.txt","w",stdout);
    37     #endif
    38     while(~scanf("%d",&n)){
    39         for(int i=0;i<n;i++){
    40             scanf("%d",&a[i]);
    41         }
    42         puts(str[solve()]);
    43     }
    44     return 0;
    45 }
    View Code

    H http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/H

    题意:输入n条竖线m条横线,每条横线有权值,从左上角走到右下角,花费定义为路径上最小权值,求最大花费。

    解法:答案只会从四种情况中产生,一是第一条竖线和最后一条横线,二是第一条横线和最后一条竖线,三是第一条和最后一条竖线加权值最大的横线,四是反之亦然。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const int inf=0x3f3f3f3f;
    22 const int M=1e5+10;
    23 int a[M];
    24 int b[M];
    25 int n,m;
    26 int get(int len,int s[]){
    27     int res=0;
    28     for(int i=1;i<len;i++){
    29         if(s[res]<s[i]){
    30             res=i;
    31         }
    32     }
    33     return s[res];
    34 }
    35 int get_min(int a,int b,int c){
    36     return min(a,min(b,c));
    37 }
    38 int solve(){
    39     int res=0;
    40     int max_a=get(n,a);
    41     int max_b=get(m,b);
    42     res=max(res,min(a[0],b[m-1]));
    43     res=max(res,min(a[n-1],b[0]));
    44     res=max(res,get_min(a[0],a[n-1],max_b));
    45     res=max(res,get_min(b[0],b[m-1],max_a));
    46     return res;
    47 }
    48 int main(){
    49     #ifdef txtout
    50     freopen("in.txt","r",stdin);
    51     freopen("out.txt","w",stdout);
    52     #endif
    53     while(~scanf("%d%d",&n,&m)){
    54         for(int i=0;i<n;i++){
    55             scanf("%d",&a[i]);
    56         }
    57         for(int i=0;i<m;i++){
    58             scanf("%d",&b[i]);
    59         }
    60         printf("%d
    ",solve());
    61     }
    62     return 0;
    63 }
    View Code

     I http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/I

    题意:A觉得素数是好的,B觉得因子个数是素数的数是好的。求L到R之间有多少个AB同时觉得好或者同时觉得不好的。

    解法:打表发现,不是平方数的一定满足,平方数有的满足,有的不满足,所以只要处理出那些平方数不合法,对一个区间,答案就是R-L+1区间内数的个数,减去在这个区间内的不合法的平方数的个数。关键如何处理出不合法的平方数。R最大10的12次方,所以平方数共有10的6次方个数。枚举每一个数,分解质因数,该数的平方就是每种质因子个数*2.根据一个公式,因子的个数等于每种因子个数 设为ai  因子个数等于 (a1+1)*。。。*(an+1);所有因子个数加1累乘。算出来后,首先平方数肯定不是素数,所以A不喜欢,那么不合法的就是b要喜欢,就是因子的个数要是素数。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const int inf=0x3f3f3f3f;
    22 const int M=1e6+10;
    23 class Sieve_primes { ///筛素数
    24     static const int M=1e6+10; ///数值范围
    25 public:
    26     int prime[M],mark[M],len; ///mark[i]存i 的最小因子
    27 public:
    28     Sieve_primes() {
    29         len=0;
    30         mt(mark,0);
    31         mark[0]=mark[1]=1;
    32         for(int i=2; i<M; i++) {
    33             if(!mark[i]) prime[len++]=mark[i]=i;
    34             for(int j=0; prime[j]*i<M; j++) {
    35                 mark[i*prime[j]]=prime[j];
    36                 if(!(i%prime[j])) break;
    37             }
    38         }
    39     }
    40     int getlen() { ///返回<M 素数的个数
    41         return len;
    42     }
    43     int getprime(int id) { ///返回第id(<len)个素数
    44         return prime[id];
    45     }
    46     bool isprime(int x) { ///素数时mark[i]==i
    47         return mark[x]==x;
    48     }
    49 }gx;
    50 LL L,R;
    51 vector<LL> a;
    52 int fac[128];
    53 int find_fac_before_sieve(int n) { //筛完素数后用,n<M
    54     int cnt=0;
    55     while(gx.mark[n]!=1) {
    56         fac[cnt++]=gx.mark[n];
    57         n/=gx.mark[n];
    58     }
    59     return cnt;
    60 }
    61 void init() {
    62     a.clear();
    63     for(int i=2;i<M;i++){
    64         int cnt=find_fac_before_sieve(i);
    65         int sum=1;
    66         for(int j=0;j<cnt;j++){
    67             int last=j;
    68             for(int k=j;k<cnt;k++){
    69                 if(fac[j]!=fac[k]) break;
    70                 last=k;
    71             }
    72             sum*=((last-j+1)*2+1);
    73             j=last;
    74         }
    75         if(gx.isprime(sum)){
    76             a.push_back(1LL*i*i);
    77         }
    78     }
    79 }
    80 LL solve() {
    81     LL tmp=upper_bound(a.begin(),a.end(),R)-lower_bound(a.begin(),a.end(),L);
    82     return R-L+1-tmp;
    83 }
    84 int main() {
    85 #ifdef txtout
    86     freopen("in.txt","r",stdin);
    87     freopen("out.txt","w",stdout);
    88 #endif
    89     init();
    90     while(~scanf("%lld%lld",&L,&R)) {
    91         printf("%lld
    ",solve());
    92     }
    93     return 0;
    94 }
    View Code

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/J

    题意:输入n个ABP串,可能是ABP的非空子序列,每次可以加一段连续的A or B or P,对于某一个串,必须按照ABP的顺序添加。问如何排列使得加的次数最小。

    解法:先把串分类,同类放一起,一共7个情况,然后7的全排列验证这个排列需要加几次,取最小值。

      1 //#define debug
      2 //#define txtout
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<cctype>
      8 #include<ctime>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<queue>
     13 #include<stack>
     14 #include<map>
     15 #include<set>
     16 #define mt(a,b) memset(a,b,sizeof(a))
     17 using namespace std;
     18 typedef long long LL;
     19 const double eps=1e-8;
     20 const double pi=acos(-1.0);
     21 const int inf=0x3f3f3f3f;
     22 const int M=1e5+10;
     23 char abp[]="ABP";
     24 char all_abp[8][8];
     25 vector<int> id[8];
     26 struct S{
     27     string str;
     28     int pid;
     29     friend bool operator <(const S &a,const S &b){
     30         return a.str<b.str;
     31     }
     32 }now;
     33 vector<S> v;
     34 string str[8];
     35 int n;
     36 int answer[M];
     37 char input[M][8];
     38 int ans_id[8];
     39 void init(){
     40     for(int i=1;i<8;i++){
     41         int len=0;
     42         for(int j=0;j<3;j++){
     43             if((i>>j)&1){
     44                 all_abp[i-1][len++]=abp[j];
     45             }
     46         }
     47         all_abp[i-1][len]=0;
     48     }
     49 }
     50 void init_id(){
     51     for(int i=0;i<8;i++){
     52         id[i].clear();
     53     }
     54     for(int i=0;i<n;i++){
     55         for(int j=0;j<7;j++){
     56             if(!strcmp(all_abp[j],input[i])){
     57                 id[j].push_back(i+1);
     58                 break;
     59             }
     60         }
     61     }
     62 }
     63 bool have(string s,char c){
     64     int ls=s.size();
     65     for(int i=0;i<ls;i++){
     66         if(s[i]==c) return true;
     67     }
     68     return false;
     69 }
     70 int get_cost(){
     71     int lv=v.size();
     72     for(int i=0;i<lv;i++){
     73         str[i]=v[i].str;
     74     }
     75     int res=0;
     76     for(int i=0;i<3;i++){
     77         for(int j=0;j<lv;j++){
     78             if(!have(str[j],abp[i])) continue;
     79             int last=j;
     80             for(int k=j;k<lv;k++){
     81                 if(have(str[k],abp[i])){
     82                     last=k;
     83                 }
     84                 else{
     85                     break;
     86                 }
     87             }
     88             res++;
     89             j=last;
     90         }
     91     }
     92     return res;
     93 }
     94 int solve(){
     95     init_id();
     96     v.clear();
     97     for(int i=0;i<7;i++){
     98         if(id[i].size()==0) continue;
     99         now.str=(string)all_abp[i];
    100         now.pid=i;
    101         v.push_back(now);
    102     }
    103     sort(v.begin(),v.end());
    104     int res=inf;
    105     int lv=v.size();
    106     do{
    107         int tmp=get_cost();
    108         if(res>tmp){
    109             res=tmp;
    110             for(int i=0;i<lv;i++){
    111                 ans_id[i]=v[i].pid;
    112             }
    113         }
    114     }while(next_permutation(v.begin(),v.end()));
    115     int la=0;
    116     for(int i=0;i<lv;i++){
    117         int len=id[ans_id[i]].size();
    118         for(int j=0;j<len;j++){
    119             answer[la++]=id[ans_id[i]][j];
    120         }
    121     }
    122     return res;
    123 }
    124 int main(){
    125     #ifdef txtout
    126     freopen("in.txt","r",stdin);
    127     freopen("out.txt","w",stdout);
    128     #endif
    129     init();
    130     while(~scanf("%d",&n)){
    131         for(int i=0;i<n;i++){
    132             scanf("%s",input[i]);
    133         }
    134         printf("%d
    ",solve());
    135         for(int i=0;i<n;i++){
    136             printf("%d%c",answer[i],i==n-1?'
    ':' ');
    137         }
    138     }
    139     return 0;
    140 }
    View Code

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/K

    题意:有n朵花,每个花的价值是一个整数,一开始站在1号,要一次给每一朵花浇水,每朵花只浇水一次,花费1,在花之间走动,花费是两朵花的距离,浇花的顺序必须保证花的价值是不递减序列。

    解法:首先按照花的价值分类,先走价值低的,比如一堆2,一堆3,必须把2的全走完,再走3.对于同一种价值的花,只可能先到左端点,再到右端点,或者先右后左。因此可以定义dp【i】【j】表示处理完前 i 种价值的花停留在 j 端点,0左端点,1右端点。4个方向都可以转移。

     1 //#define debug
     2 //#define txtout
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<cctype>
     8 #include<ctime>
     9 #include<iostream>
    10 #include<algorithm>
    11 #include<vector>
    12 #include<queue>
    13 #include<stack>
    14 #include<map>
    15 #include<set>
    16 #define mt(a,b) memset(a,b,sizeof(a))
    17 using namespace std;
    18 typedef long long LL;
    19 const double eps=1e-8;
    20 const double pi=acos(-1.0);
    21 const LL inf=0x3f3f3f3f3f3f3f3fLL;
    22 const int M=1e5+10;
    23 int a[M];
    24 int b[M];
    25 int l[M];
    26 int r[M];
    27 int n;
    28 map<int,int> mp;
    29 LL dp[M][2];
    30 int init_l_r(){
    31     for(int i=0;i<n;i++){
    32         b[i]=a[i];
    33     }
    34     sort(b,b+n);
    35     int Index=0;
    36     for(int i=0;i<n;i++){
    37         if(!mp.count(b[i])){
    38             mp[b[i]]=Index++;
    39         }
    40     }
    41     int len=mp.size();
    42     for(int i=0;i<len;i++){
    43         l[i]=-1;
    44     }
    45     for(int i=0;i<n;i++){
    46         int to=mp[a[i]];
    47         if(l[to]==-1){
    48             l[to]=i;
    49         }
    50         r[to]=i;
    51     }
    52     return len;
    53 }
    54 void init_dp(int len){
    55     for(int i=0;i<len;i++){
    56         for(int j=0;j<2;j++){
    57             dp[i][j]=inf;
    58         }
    59     }
    60 }
    61 int get_l_r(int i,int j){
    62     if(!j) return l[i]; return r[i];
    63 }
    64 LL getcost(int i,int j,int k){
    65     int s1=get_l_r(i,j);
    66     int s2=get_l_r(i+1,k^1);
    67     int s3=get_l_r(i+1,k);
    68     return abs(s1-s2)+abs(s2-s3);
    69 }
    70 LL solve(){
    71     int len=init_l_r();
    72     init_dp(len);
    73     dp[0][1]=r[0];
    74     for(int i=0;i+1<len;i++){
    75         for(int j=0;j<2;j++){
    76             for(int k=0;k<2;k++){
    77                 dp[i+1][k]=min(dp[i+1][k],dp[i][j]+getcost(i,j,k));
    78             }
    79         }
    80     }
    81     return n+min(dp[len-1][0],dp[len-1][1]);
    82 }
    83 int main(){
    84     #ifdef txtout
    85     freopen("in.txt","r",stdin);
    86     freopen("out.txt","w",stdout);
    87     #endif
    88     while(~scanf("%d",&n)){
    89         for(int i=0;i<n;i++){
    90             scanf("%d",&a[i]);
    91         }
    92         printf("%lld
    ",solve());
    93     }
    94     return 0;
    95 }
    View Code

    L  http://acm.hust.edu.cn/vjudge/contest/view.action?cid=96950#problem/L

    题意:输入n场比赛名字,时间,题数,提交数,每次提交的题号,结果,最后比赛名字时间原样输出,没提交的题输出. 提交通过输出o 未通过X。

    解法:模拟题,怎么说怎么做。

      1 //#define debug
      2 //#define txtout
      3 #include<cstdio>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<cctype>
      8 #include<ctime>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<vector>
     12 #include<queue>
     13 #include<stack>
     14 #include<map>
     15 #include<set>
     16 #define mt(a,b) memset(a,b,sizeof(a))
     17 using namespace std;
     18 typedef long long LL;
     19 const double eps=1e-8;
     20 const double pi=acos(-1.0);
     21 const int inf=0x3f3f3f3f;
     22 const int M=1e2+10;
     23 struct G{
     24     char name[M],date[16];
     25     int type[16],number;
     26     void init(){
     27         for(int i=0;i<13;i++){
     28             type[i]=0;
     29         }
     30     }
     31     void add(char a,char b){
     32         int to=a-'A';
     33         if(b=='A'){
     34             type[to]=2;
     35             return ;
     36         }
     37         if(type[to]==0){
     38             type[to]=1;
     39         }
     40     }
     41 }g[M];
     42 int n,m;
     43 char buffer[M];
     44 char str[]=".xo";
     45 char divide[]="+------------------------------+--------+-------------+";
     46 char titles[]="|Contest name                  |Date    |ABCDEFGHIJKLM|";
     47 void get_line(char s[]){
     48     int ls=0;
     49     while(true){
     50         char c=getchar();
     51         if(c=='
    ') break;
     52         s[ls++]=c;
     53     }
     54     s[ls]=0;
     55 }
     56 void output_string(char s[]){
     57     for(int i=0;s[i];i++){
     58         putchar(s[i]);
     59     }
     60 }
     61 void output_space(int x){
     62     for(int i=0;i<x;i++){
     63         putchar(' ');
     64     }
     65 }
     66 void output_type(int x){
     67     for(int i=0;i<g[x].number;i++){
     68         putchar(str[g[x].type[i]]);
     69     }
     70 }
     71 void output(int id){
     72     putchar('|');
     73     output_string(g[id].name);
     74     output_space(30-strlen(g[id].name));
     75     putchar('|');
     76     output_string(g[id].date);
     77     putchar('|');
     78     output_type(id);
     79     output_space(13-g[id].number);
     80     puts("|");
     81     puts(divide);
     82 }
     83 int main(){
     84     #ifdef txtout
     85     freopen("in.txt","r",stdin);
     86     freopen("out.txt","w",stdout);
     87     #endif
     88     while(~scanf("%d",&n)){
     89         getchar();
     90         for(int i=0;i<n;i++){
     91             get_line(g[i].name);
     92             get_line(g[i].date);
     93             scanf("%d%d",&g[i].number,&m);
     94             getchar();
     95             g[i].init();
     96             while(m--){
     97                 get_line(buffer);
     98                 g[i].add(buffer[0],buffer[2]);
     99             }
    100         }
    101         puts(divide);
    102         puts(titles);
    103         puts(divide);
    104         for(int i=0;i<n;i++){
    105             output(i);
    106         }
    107     }
    108     return 0;
    109 }
    View Code

    end

  • 相关阅读:
    《老男孩》
    java中四种阶乘的计算
    DataOutputStream的乱码问题
    java中飞clone方法
    类反射的简单例子
    PHP: 如何连接oracle数据库进行数据读取
    .NET : 如何读取图片中的元数据信息
    重新审视REST
    PHP 的历史
    Image File Format Specifications {转载}
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/4918018.html
Copyright © 2011-2022 走看看