模拟算法练习

codevs 

1.1507 酒厂选址

 1 #define N  10010
 2 #include<iostream>
 3 using namespace std;
 4 #include<cstdio>
 5 #include<cstring>
 6 int sum[N],z[N],a[N];
 7 long long minn=-1;
 8 int n;
 9 int read()
10 {
11     int ans=0;char s;
12     s=getchar();
13     while(s<'0'||s>'9') s=getchar();
14     while(s>='0'&&s<='9')
15     {
16         ans=ans*10+s-'0';
17         s=getchar();
18     }
19     return ans;
20 }
21 void input()
22 {
23     n=read();
24     for(int i=1;i<=n;++i)
25     {
26         z[i]=read();
27         a[i]=read();
28           
29     }
30     sum[1]=0;
31     for(int i=2;i<=n;++i)
32       sum[i]=sum[i-1]+a[i-1];
33 }
34 inline int min_count(int k,int i)
35 {
36     if(k>i)
37     {
38         return min((sum[k]-sum[i])*z[i],(sum[n]-sum[k]+sum[i]+a[n])*z[i]);
39     }
40     else 
41     {
42         return min((sum[i]-sum[k])*z[i],(a[n]+sum[n]-sum[i]+sum[k])*z[i]);
43     }
44 }
45 void chuli(int k)
46 {
47     long long ans=0;
48     for(int i=1;i<=n;++i)
49     {
50         if(i==k) continue;
51         ans+=min_count(k,i);
52     }
53     if(minn<0)
54     minn=ans;
55     else minn=min(ans,minn);
56 }
57 int main()
58 {
59     input();
60     for(int i=1;i<=n;++i)
61       chuli(i);
62     cout<<minn<<endl;
63     return 0;
64 }
View Code

2.2621 土地侵蚀

 1 #define pi 3.141592654
 2 #include<iostream>
 3 using namespace std;
 4 #include<cstdio>
 5 #include<cmath>
 6 double x,y,temp=50,sum=0;
 7 int year=0;
 8 int main()
 9 {
10     cin>>x>>y;
11     if(x<0||y<0)
12     {
13         cout<<0<<endl;
14         return 0;
15     }
16     while(true)
17     {
18         double r=2*sum/pi;
19         if(x*x+y*y<r)
20         {
21             printf("%d\n",year);
22             break;
23         }
24         year++;
25         sum+=50;
26     }
27     return 0;
28 }
View Code

3.3016 质子撞击炮 II

 1 #define N 1050
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 int jz[N][N];
 7 int n;
 8 int xx[9]={0,0,0,1,1,1,-1,-1,-1};
 9 int yy[9]={0,1,-1,0,1,-1,0,1,-1};
10 int read()
11 {
12     int ans=0;
13     char s;
14     while(s<'0'||s>'9') s=getchar();
15     while('0'<=s&&s<='9')
16     {
17         ans=ans*10+s-'0';
18         s=getchar();
19     }
20     return ans;
21 }
22 int main()
23 {
24     memset(jz,127,sizeof(jz));
25     int sum=0;
26     n=read();
27     for(int i=1;i<=n;++i)
28       for(int j=1;j<=n;++j)
29       {
30           jz[i][j]=read();
31           if(jz[i][j]==0) jz[i][j]=N;
32       }
33     for(int i=1;i<=5;++i)
34     {
35         int x,y;
36         x=read();y=read();
37         jz[x][y]--;
38         for(int j=0;j<9;++j)
39         {
40             int x1=x+xx[j],y1=y+yy[j];
41             jz[x1][y1]--;
42             if(jz[x1][y1]<=0)
43             {
44                 sum++;
45                 jz[x1][y1]=N;
46             }
47         }
48     }
49     cout<<sum<<endl;
50     return 0;
51 }
View Code

4.2927 集合(膜拜FTC大神(虽然我也不知道是谁))

 时间限制: 2 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 题目描述 Description

    给出n个集合,每个集合中有若干个数。

    有m个询问,每次询问两个数a,b,判断a、b是否同时存在于某一个集合中。

输入描述 Input Description

    第一行为n。

    接下来的n行,每行描述一个集合,每行的第一个数为该集合中数的个数k,接下来有k个数。数字可能有重复。

    第n+2行为m。

    接下来的m行,每行两个数a、b,表示一个询问。

输出描述 Output Description

    对于每次询问,输出一行。若a、b同时存在于某一个集合中,输出Y,否则输出N。

样例输入 Sample Input

3

2 1 2

3 2 3 4

3 2 5 7

2

1 3

2 7

样例输出 Sample Output

N

Y

数据范围及提示 Data Size & Hint
n<=1000,k<=10000,m<=2000000,集合中的数字小于10000,a、b<=32767,不保证a!=b。不保证任意两个集合不同。集合中的数与询问的数均为非负整数。
  1 /*我一开始用set爆了空间,用Hash又超时了,还是FTC大神的代码牛B*/
  2 /*----------------超时代码---------------------------------*/
  3 #include<cstdio>
  4 #include<iostream>
  5 #define N 1001
  6 #include<cstring>
  7 #define mod 10007
  8 using namespace std;
  9 int n,k,m,a,b;
 10 struct Hash{
 11     int s[mod];
 12     Hash(){memset(s,-1,sizeof(s));}
 13     void insert(int x)
 14     {
 15         int k=x%mod;
 16         while(s[k]!=x&&s[k]!=-1)
 17         {
 18             k++;
 19             k%=mod;
 20         }
 21         s[k]=x;
 22     }
 23     bool count(int x)
 24     {
 25         int k=x%mod;
 26         int t=0;
 27         while(s[k]!=x)
 28         {
 29             k++;
 30             k%=mod;
 31             t++;
 32             if(t>mod) break;
 33         }    
 34         if(t>mod) return false;
 35         return true;
 36     }
 37 }se[N];
 38 int read()
 39 {
 40     int ans=0;char s;
 41     s=getchar();
 42     while(s<'0'||s>'9') s=getchar();
 43     while('0'<=s&&s<='9')
 44     ans=ans*10+s-'0',s=getchar();
 45     return ans;
 46 }
 47 int main()
 48 {
 49     n=read();
 50     for(int i=1;i<=n;++i)
 51     {
 52         k=read();
 53         while(k--)
 54         {
 55             int a;
 56             a=read();
 57             se[i].insert(a);
 58         }
 59     }
 60     m=read();
 61     while(m--)
 62     {
 63         a=read();b=read();
 64         if(a>10000||b>10000)
 65         {
 66             printf("N\n");
 67             continue;
 68         }
 69         for(int i=1;i<=n;++i)
 70         {
 71             if(se[i].count(a)&&se[i].count(b))
 72             {
 73                 printf("Y\n");
 74                 break;
 75             }
 76             if(i==n)
 77             printf("N\n");
 78         }
 79     }
 80     return 0;
 81 }
 82 /*----------------------正确代码以及神一般的思路------------------------*/
 83 /*这种方法对于数的范围较小但是集合数目很多,数的量很大,的题目,很实用的*/
 84 #include<iostream>
 85 using namespace std;
 86 #include<cstdio>
 87 #define N 10002
 88 unsigned long long topt[N][20]={0};/*1000/64==15*/
 89 int n,m,k,a,b;
 90 int read()
 91 {
 92     int ans=0;char s;
 93     s=getchar();
 94     while(s<'0'||s>'9') s=getchar();
 95     while('0'<=s&&s<='9')
 96     {
 97         ans=ans*10+s-'0';
 98         s=getchar();
 99     }
100     return ans;
101 }
102 inline void insert(int i,int x)
103 {
104     topt[x][i/64]|=(1ull<<(i%64));
105  /*第一维表示的是原数,还要有一个1000位的二进制表示存在于哪个集合当中,因为1000位太多了,无论是第二维还是数组的值都是存不开的,就平分,第二维储存着1000位数分成了几分,集合的数储存着这一份中的这些集合有没有这个数,所以要i/64,i%64,使用无符号长整形ull后缀1,可以解决符号位的影响*/
106 }
107 int main()
108 {
109     n=read();
110     for(int i=1;i<=n;++i)
111     {
112         k=read();
113         for(int j=1;j<=k;++j)
114         {
115             a=read();
116             insert(i,a);
117         }
118     }
119     m=read();
120     while(m--)
121     {
122         a=read();b=read();
123         if(a>10000||b>10000)
124         {
125             printf("N\n");
126             continue;
127         }
128         for(int i=0;i<=16;i++)
129         {/*查询时,直接把每一份位运算,只要不是0,就说明在同一个集合,多么神奇的做法*/
130             if(topt[a][i]&topt[b][i])
131             {
132                 printf("Y\n");break;
133             }
134             if(i==16)
135             {
136                 printf("N\n");
137             }
138         }
139     }
140     return 0;
141 }

5.1445 送Q币

 1 #include<iostream>
 2 #define N 15
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 int sum[N]={0};
 7 #include<map>
 8 map<string,int>ma;
 9 int ksum[N];
10 string s[N];
11 int n,topt;
12 int main()
13 {
14     scanf("%d",&n);
15     for(int i=1;i<=n;++i)
16     {
17         cin>>s[i];
18         ma[s[i]]=i;
19         sum[i]=0;
20     }
21     string ss;
22     while(cin>>ss)
23     {
24         int k=ma[ss];
25         int num,numk;
26         scanf("%d",&num);
27         ksum[k]=num;
28         sum[k]+=num;
29         string nam;
30         scanf("%d",&numk);
31         if(numk==0) continue;
32         int mony=num/numk;
33         sum[k]=sum[k]-mony*numk;
34         while(numk--)
35         {
36             cin>>nam;
37             int t=ma[nam];
38             sum[t]+=mony;
39         }
40     }
41     for(int i=1;i<=n;++i)
42     {
43         cout<<s[i]<<" "<<sum[ma[s[i]]]-ksum[ma[s[i]]]<<endl;
44     }
45     return 0;
46 }
View Code

6.1054 电梯

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 long long tim=0;
 5 int n;
 6 int now=0,k;
 7 int main()
 8 {
 9     scanf("%d",&n);
10     while(n--)
11     {
12         scanf("%d",&k);
13         if(k>=now)
14         {
15             tim+=(k-now)*6+5;
16         }
17         else {
18         tim+=(now-k)*4+5;
19         }
20         now=k;
21     }
22     cout<<tim<<endl;
23     return 0;
24 }
View Code

7.2622 数字序列

 1 #define N 1001
 2 #include<iostream>
 3 using namespace std;
 4 #include<cstdio>
 5 int sum[N];
 6 int f[N][N];
 7 int main()
 8 {
 9     int ans=0;
10     int n;
11     scanf("%d",&n);
12     for(int i=1;i<=n;++i)
13     {
14         scanf("%d",&sum[i]);
15         sum[i]+=sum[i-1];
16     }
17     for(int l=1;l<=n;++l)
18       for(int i=1,j=l+i-1;j<=n&&i<=n;++i,++j)
19       {
20           f[i][j]=sum[j]-sum[i-1];
21           ans=max(ans,f[i][j]);
22           
23       }
24     cout<<ans<<endl;
25     return 0;
26 }
View Code

8.1055 气球

 1 #define N 101
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 using namespace std;
 7 #include<map>
 8 bool cmp(char a[20],char b[20])
 9 {
10     int i=0;
11     for(;i<14;++i)
12     {
13         if(a[i]<b[i]) return true;
14         if(b[i]<a[i]) return false;
15     }
16 }
17 struct Node{
18     int sum;
19     char nam[20];
20     Node()
21     {sum=0;memset(nam,0,sizeof(nam));}
22     
23     bool operator <(const Node &g)
24     const {
25         if(sum>g.sum) 
26           return true;
27         if(sum<g.sum) 
28           return false;
29         if(strcmp(nam,g.nam)<0)  return true;
30         else return 0;
31 /*strcmp是返回正负数和0,c++上非0数是true,!是把非0数变为0,而不是把负数变为正数,再用strcmp是要注意这个区别*/
32         }
33 }node[N];
34 int n;
35 map<string,int>ma;
36 int main()
37 {
38     scanf("%d",&n);
39     char k[20];
40     int t=0;
41     for(int i=1;i<=n;++i)
42     {
43         scanf("%s",k);
44         if(ma[k]==0)
45         {
46             t++;
47             ma[k]=t;
48             strcpy(node[t].nam,k);
49             node[t].sum++;
50         }
51         else {
52             int q=ma[k];
53             node[q].sum++;
54         }
55     }
56     sort(node+1,node+t+1);
57     printf("%d\n",t);
58     int topt=-1;
59     for(int i=1;i<=t;++i)
60     {
61         if(node[i].sum!=topt)
62         {
63             topt=node[i].sum;
64             printf("%d\n%s\n",node[i].sum,node[i].nam);
65         }
66         else printf("%s\n",node[i].nam);
67     }
68     return 0;
69 }
View Code

9.3138 栈练习2

 1 #include<iostream>
 2 #include<vector>
 3 #include<cstdio>
 4 #include<stack>
 5 using namespace std;
 6 int n,k,topt,top=0;
 7 stack<int>stac;
 8 int main()
 9 {
10     scanf("%d",&n);
11     while(n--)
12     {
13         scanf("%d",&topt);
14         if(topt==1)
15         {
16             scanf("%d",&k);
17             stac.push(k);
18         }
19         else 
20         {
21             if(stac.empty())
22             {
23                 printf("impossible!\n");
24                 return 0;
25             }
26             stac.pop();
27         }
28     }
29     if(stac.empty())
30       printf("impossible!\n");
31     else printf("%d\n",stac.top());
32     return 0;
33 }
View Code

10.3139 栈练习3

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 #include<stack>
 5 stack<int>stac;
 6 int main()
 7 {
 8     int n;
 9     scanf("%d",&n);
10     int topt,k;
11     while(n--)
12     {
13         scanf("%d",&topt);
14         if(topt==1)
15         {
16             scanf("%d",&k);
17             stac.push(k);
18         }
19         if(topt==2)
20         {
21             stac.pop();
22         }
23         if(topt==3)
24         {
25             printf("%d\n",stac.top());
26         }
27     }
28     return 0;
29 }
View Code

11.1067 机器翻译

 1 #include<iostream>
 2 using namespace std;
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 queue<int>que;
 7 bool flag[1001]={0};
 8 int n,m,k;
 9 int now=0;
10 long long ans=0;
11 int main()
12 {
13     scanf("%d%d",&m,&n);
14     for(int i=1;i<=n;++i)
15     {
16         scanf("%d",&k);
17         if(flag[k]) continue;
18         ans++;
19         now++;
20         if(now>m)
21         {
22             now--;
23             int l=que.front();
24             que.pop();
25             flag[l]=false;
26         }
27         flag[k]=true;
28         que.push(k);
29         
30         
31     }
32     cout<<ans<<endl;
33     return 0;
34 }
View Code
posted @ 2016-05-29 19:13  csgc0131123  阅读(224)  评论(0编辑  收藏  举报