2015-04-10 12:57:22

总结:定期的 asc 训练赛...

  第一场打得不是很认真... 中间走神了,以后尽量选在整块的时间来打 asc 。

  5h 过了 4题,5h1min过了第 5题,赛后补齐了剩下的3题... 说实话补最后一题(耗时2days)都差点放弃了。。

  ※本场的一些收获:

  (1)完善了高精度模板。

  (2)学习了dinic当前弧优化。

  (3)学习了上下界流的第二种建图方式。

  (4)收获了高斯消元另一个模型。

  (5)学习了如何判断点在多边形内。

  (6)学习了如何利用dfs树找简单环。

 

A题

  可以把题目转化为:给出N,找到一个K与N互质且K<=N/2。

  试了一些数据发现规律:如果N为奇数,那么答案为(N-1)/2;

  如果N为偶数,那么判断N/2的奇偶性,若N/2为偶则答案为N/2-1,若N/2为奇数则答案为N/2-2。

  由于题目的数据范围很大... 需要上高精度。

  1 #include <cstdio>
  2 #include <string>
  3 #include <cstring>
  4 #include <iostream>
  5 using namespace std;
  6 const int maxn = 3000;
  7 
  8 struct bign{
  9     int len,s[maxn + 5];
 10 
 11     //初始化与赋值
 12     bign(){
 13         memset(s,0,sizeof(s));
 14         len = 1;//因为0的存在
 15     }
 16 
 17     bign operator = (const char *num){
 18         len = strlen(num);
 19         for(int i = 0; i < len; ++i)
 20             s[i] = num[len - i - 1] - '0';//倒序转化成数字
 21         return *this;
 22     }
 23 
 24     bign operator = (int num){
 25         char ts[maxn + 5];
 26         sprintf(ts,"%d",num);
 27         *this = ts;
 28         return *this;
 29     }
 30 
 31     bign(int num){
 32         *this = num;
 33     }
 34 
 35     bign(const char *num){
 36         *this = num;
 37     }
 38     //bign的str型转化
 39     string str() const{
 40         string res = "";
 41         for(int i = len - 1; i >= 0; --i)
 42             res +=  (char)(s[i] + '0');
 43         if(res == "")
 44             res = "0";
 45         return res;
 46     }
 47     //运算符重载
 48     //高精度加
 49     bign operator + (const bign & b) const{
 50         bign sum;
 51         sum.len = 0;
 52         for(int i = 0, g = 0; g || i < max(len,b.len); ++i){
 53             int x = g;//x:暂存和,g:进位
 54             if(i < len) x += s[i];
 55             if(i < b.len) x += b.s[i];
 56             sum.s[sum.len++] = x % 10;
 57             g = x / 10;
 58         }
 59         return sum;
 60     }
 61 
 62     //高精度减
 63     bign operator - (const bign & b) const{
 64         bign dif;
 65         int maxlen = (len > b.len) ? len : b.len;
 66         for(int i = 0; i < maxlen; ++i){
 67             dif.s[i] += s[i] - b.s[i];
 68             if(dif.s[i] < 0){
 69                 dif.s[i] += 10;
 70                 --dif.s[i + 1];
 71             }
 72         }
 73         dif.len = maxlen;
 74         while(dif.s[dif.len - 1] == 0 && dif.len > 1)
 75             --dif.len;
 76         return dif;
 77     }
 78 
 79     //高精度乘,实际上加和乘对进位的处理有所不同
 80     bign operator * (const bign &b) const{
 81         bign pro;
 82         pro.len = 0;
 83         for(int i = 0; i < len; ++i){
 84             for(int j = 0; j < b.len; ++j){
 85                 pro.s[i + j] += (s[i] * b.s[j]);
 86                 pro.s[i + j + 1] += pro.s[i + j] / 10;
 87                 pro.s[i + j] %= 10;
 88             }
 89         }
 90         pro.len = len + b.len + 1;//这里注意pro.len初始值可能是题目数字范围两倍
 91         while(pro.s[pro.len - 1] == 0 && pro.len > 1)
 92             --pro.len;//最后一位不管是不是0都不能让len - 1
 93         if(pro.s[pro.len])
 94             ++pro.len;//这句有待商讨
 95         return pro;
 96     }
 97 
 98     //高精度乘以低精度
 99     bign operator * (const int num) const{
100         int c = 0,t;
101         bign pro;
102         for(int i = 0; i < len; ++i){
103             t = s[i] * num + c;
104             pro.s[i] = t % 10;
105             c = t / 10;
106         }
107         pro.len = len;
108         while(c != 0){
109             pro.s[pro.len++] = c % 10;
110             c /= 10;
111         }
112         return pro;
113     }
114 
115     //高精度除,模拟连减
116     bign operator / (const bign & b) const{
117         bign quo,f;
118         for(int i = len - 1; i >= 0; --i){
119             f = f * 10;
120             f.s[0] = s[i];
121             while(f >= b){
122                 f = f - b;
123                 ++quo.s[i];
124             }
125         }
126         quo.len = len;
127         while(quo.s[quo.len - 1] == 0 && quo.len > 1)
128             --quo.len;
129         return quo;
130     }
131 
132     //比较运算符
133     bool operator < (const bign & b) const{
134         if(len != b.len) return len < b.len;
135         for(int i = len - 1; i >= 0; --i)//从高位开始比较
136             if(s[i] != b.s[i])
137                 return s[i] < b.s[i];
138         //如果 本身 == b
139         return false;
140     }
141 
142     bool operator > (const bign &b) const{
143         return b < *this;//代表 本身 > b
144     }
145 
146     bool operator <= (const bign &b) const{
147         return !(b < *this);//带表 !(本身 > b)
148     }
149 
150     bool operator >= (const bign &b) const{
151         return !(*this < b);
152     }
153 
154     bool operator != (const bign &b) const{
155         return *this < b || b < *this;
156     }
157 
158     bool operator == (const bign &b) const{
159         return !(*this < b) && !(b < *this);
160     }
161 
162     friend istream & operator >> (istream & in,bign & x);
163     friend ostream & operator << (ostream & out,const bign & x);
164 };
165 
166 istream & operator >> (istream & in,bign & x){
167     string ts;
168     in >> ts;
169     x = ts.c_str();
170     return in;
171 }
172 
173 ostream & operator << (ostream & out,const bign & x){
174     out << x.str();
175     return out;
176 }
177 int main(){
178     freopen("china.in","r",stdin);
179     freopen("china.out","w",stdout);
180     bign N;
181     bign one = 1,two = 2;
182     cin >> N;
183     bign hf = N / 2;
184     int suf = N.s[0];
185     if(suf & 1){
186         cout << hf << endl;
187     }
188     else{
189         if(hf.s[0] & 1) cout << hf - two << endl;
190         else cout << hf - one << endl;
191     }
192     return 0;
193 }
View Code

相关文章:

  • 2021-06-28
  • 2022-01-10
  • 2021-09-17
  • 2022-12-23
  • 2021-12-10
猜你喜欢
  • 2022-02-18
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-03-03
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案