博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2016 Multi-University Training Contest 2 部分题解
阅读量:6480 次
发布时间:2019-06-23

本文共 8095 字,大约阅读时间需要 26 分钟。

  1009,直接贪心,只要让后面的尽量小,第一位和第二位尽量大即可。

  

  1011,直接统计奇数的字母的个数,然后用偶数的个数平均分配到它们上面即可。代码如下:

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 int main() 7 { 8 int T; 9 scanf("%d",&T);10 while(T--)11 {12 int n;13 int odd = 0, even = 0;14 scanf("%d",&n);15 for(int i=1;i<=n;i++)16 {17 int t;18 scanf("%d",&t);19 if(t % 2)20 {21 odd ++;22 even += (t - 1) / 2;23 }24 else even += t / 2;25 }26 if(odd == 0)27 {28 printf("%d\n",even << 1);29 }30 else31 {32 printf("%d\n",even / odd * 2 + 1);33 }34 }35 }
View Code

 

  1001,用二次函数做即可,把阿尔法看做一个未知数。分析过程如下:

代码如下:

1 #include 
2 #include
3 #include
4 using namespace std; 5 typedef long long ll; 6 7 int main() 8 { 9 int T;10 scanf("%d",&T);11 while(T--)12 {13 ll sum = 0, sum2 = 0;14 int n;15 scanf("%d",&n);16 for(int i=1;i<=n;i++)17 {18 int t;19 scanf("%d",&t);20 if(t<0) t = -t; // 全部值都变正21 sum += t;22 sum2 += (ll)t*t;23 }24 sum *= sum;25 if(sum == 0)26 {27 printf("I64%d/%d\n",sum2,1);28 continue;29 }30 ll gd = __gcd(sum,(ll)n);31 if(gd > 1)32 {33 sum /= gd;34 n /= gd;35 }36 sum2 *= n;37 sum2 -= sum;38 if(sum2 == 0)39 {40 printf("%d/%d\n",0,1);41 continue;42 }43 gd = __gcd(sum2,(ll)n);44 if(gd > 1)45 {46 sum2 /= gd;47 n /= gd;48 }49 printf("%I64d/%d\n",sum2,n);50 }51 }
View Code

 

  1012,题意是匹配串和原串去匹配,原串的相应区间可以对某些位置进行操作。设位置x是可以操作的,那么x和它下一个位置进行交换;同时,两个x之间的间隔必须大于等于1。直接暴力即可,代码如下:

1 #include 
2 using namespace std; 3 4 char s[(int)1e5+5],t[5000+5]; 5 char ans[(int)1e5+5]; 6 int n,m; 7 8 bool isok(int pos) 9 {10 int j = 1;11 for(int i=pos;i<=pos+m-1;)12 {13 if(s[i] == t[j])14 {15 i++,j++;16 }17 else18 {19 20 if(i == pos+m-1) return false;21 if(s[i] != t[j+1] || s[i+1] != t[j]) return false;22 else i += 2,j += 2;23 }24 }25 return true;26 }27 28 int main()29 {30 int T;31 scanf("%d",&T);32 while(T--)33 {34 scanf("%d%d",&n,&m);35 scanf("%s",s+1);36 scanf("%s",t+1);37 for(int i=1;i<=n;i++) ans[i] = '0';38 for(int i=1;i+m-1<=n;i++)39 {40 if(isok(i)) ans[i] = '1';41 else ans[i] = '0';42 }43 for(int i=1;i<=n;i++)44 {45 printf("%c",ans[i]);46 }47 puts("");48 }49 }
View Code

   

  1005,找出共线的点的集合(集合内点的个数大于等于2,可以是重点)。最初的做法是,找出所有的直线方程,统计这上面的点的个数,然后这条线上的集合的个数就是C(2,m)+C(3,m)+...+C(m,m) = 2^m - m - 1。但是我们实现用了大量的map,可能是因为这一点,超时了。TLE的代码如下:

1 #include
2 #include
3 #include
4 #include
5 #include
6 #define ll long long 7 using namespace std; 8 const int mod = (int)1e9 + 7; 9 //const ll p = 257; 10 11 struct line 12 { 13 ll a,b,c; 14 bool operator <(const line & A) const 15 { 16 return a==A.a? b==A.b?c
>= 1; 36 x = (x*x) % mod; 37 } 38 return ans; 39 } 40 41 map
M; 42 map
M2; 43 map
M3; 44 //set
S; 45 46 bool isequel(point a,point b) 47 { 48 if(a.x==b.x && a.y==b.y) return 1; 49 return 0; 50 } 51 52 void get(ll &a,ll &b,ll &c,point p1,point p2) 53 { 54 ll x1 = p1.x,y1 = p1.y; 55 ll x2 = p2.x,y2 = p2.y; 56 c = x1 - x2; 57 a = y1 - y2; 58 b = x1*y2-y1*x2; 59 } 60 61 ll getn(ll now) 62 { 63 for(ll i = 1 ;;i++) 64 { 65 if(i*(i+1)/2 == now) return i+1; 66 } 67 } 68 69 void modify(ll& a , ll & b, ll &c) 70 { 71 if(a==0 && b == 0) {c=1;return;} 72 if(b==0 && c == 0) {a=1;return;} 73 if(a==0 && c == 0) {b=1;return;} 74 if(a && b && c) 75 { 76 int gd = __gcd(a,__gcd(b,c)); 77 a /= gd; 78 b /= gd; 79 c /= gd; 80 } 81 else 82 { 83 if(a==0) 84 { 85 int gd = __gcd(b,c); 86 b /= gd; 87 c /= gd; 88 } 89 else if(b==0) 90 { 91 int gd = __gcd(a,c); 92 a /= gd; 93 c /= gd; 94 } 95 else if(c==0) 96 { 97 int gd = __gcd(a,b); 98 a /= gd; 99 b /= gd;100 }101 }102 }103 104 int main()105 {106 int T;107 scanf("%d",&T);108 while(T--)109 {110 M.clear();111 M2.clear();112 M3.clear();113 //S.clear();114 int n;115 scanf("%d",&n);116 for(int i=1;i<=n;i++)117 {118 ll x,y;119 scanf("%I64d%I64d",&x,&y);120 p[i] = (point){x,y};121 M2[p[i]] ++;122 }123 124 for(map
::iterator it=M2.begin();it!=M2.end();it++)125 {126 map
::iterator it2 = it;127 it2++;128 for(;it2!=M2.end();it2++)129 {130 //if(isequel((*it).first,(*it2).first)) continue;131 ll a,b,c;132 get(a,b,c,(*it).first,(*it2).first);133 modify(a,b,c);134 M[(line){a,b,c}] += (*it).second + (*it2).second;135 M3[(line){a,b,c}] ++;136 //S.insert(p[i]);137 //printf("%d %d %d !!\n",i,j,M[(line){a,b,c}]);138 }139 }140 141 ll ans = 0;142 143 for(map
::iterator it = M.begin();it!=M.end();it++)144 {145 ll nownow = (*it).second;146 //cout << now <<"!!"<
::iterator itt = M3.find((*it).first);149 ll now = ((*itt).second);150 //ll now = M3.second;151 ll n = getn(now);152 ll nn = nownow/(n-1);153 ans += (qpow(2,nn)-nn-1);154 ans %= mod;155 }156 for(map
::iterator it = M2.begin();it!=M2.end();it++)157 {158 ll now = (*it).second;159 if(now<=1) continue;160 ans += (qpow(2,now)-now-1);161 }162 163 cout << ans <
View Code

看了标程以后觉得他的方法很好。大概是这样子的:先对所有的点按照x,y的大小排序,然后对每一个点,算出包含了这个点的的集合的个数。具体见代码和注释:

1 #include 
2 typedef long long ll; 3 using namespace std; 4 const int N = 1000 + 50; 5 const int mod = (int)1e9 + 7; 6 7 struct point 8 { 9 int x, y;10 point() {}11 point(int _x, int _y): x(_x), y(_y) {}12 point operator - (const point & temp) const13 {14 return point(x - temp.x, y - temp.y); 15 }16 bool operator < (const point & temp) const17 {18 return x < temp.x || (x == temp.x && y < temp.y);19 }20 bool operator == (const point & temp) const21 {22 return x == temp.x && y == temp.y;23 }24 void reduce()25 {26 int g = __gcd(abs(x), abs(y));27 if(g) {x /= g; y /= g;}28 }29 } p[N], Q[N];30 31 int pw[N];32 void init()33 {34 pw[0] = 1;35 for(int i = 1; i < N; i++) pw[i] = pw[i-1] * 2 % mod;36 }37 38 void update(int &x, int y)39 {40 x += y;41 if(x >= mod) x -= mod;42 }43 44 void run()45 {46 int n;scanf("%d", &n);47 int ans = 0;48 for(int i = 1; i <= n; i++) scanf("%d%d",&p[i].x, &p[i].y);49 // 先要对所有点排序,不然共线向量会有正负的区别50 sort(p + 1, p + 1 + n);51 for(int i = 1; i <= n; i++) 52 {53 int cnt = 0, tot = 0;54 // cnt 是除了i这个点以外的重点的个数55 // m是 这个点位置以外的点的个数56 for(int j = i + 1; j <= n; j++)57 {58 if(p[i] == p[j]) cnt++;59 else Q[++tot] = p[j] - p[i]; // Q 放的是向量60 }61 update(ans, pw[cnt] - 1); // 这里是对重点们形成集合的贡献62 // 计算方式是选出i这个点,之后从剩下的cnt这么多个点中选出至少一个的种类数63 // 那么,贡献就是C(1,cnt)+C(2,cnt)+...+C(cnt,cnt) = 2^cnt - 164 65 for(int j = 1; j <= tot; j++) Q[j].reduce();66 sort(Q + 1, Q + 1 + tot);67 for(int x = 1, y; x <= tot; x = y)68 {69 for(y = x; y <= tot && Q[x] == Q[y]; y++) ;70 // y 出来的时候已经是 Q[x] != Q[y] 了,因此 y-x 正好是这一个角度上其他的点的个数71 // 这时候,对答案的贡献是,从除了i这个点以外的重点中选出任意个数的点的种类数72 // 和从这个角度上的其他点中选出至少1个点的种类数的乘积73 update(ans, 1LL * pw[cnt] * (pw[y - x] - 1) % mod); 74 }75 }76 printf("%d\n", ans);77 }78 79 int main()80 {81 init();82 int T;scanf("%d", &T);83 while(T--) run();84 return 0;85 }
View Code

 

 

转载于:https://www.cnblogs.com/zzyDS/p/5694406.html

你可能感兴趣的文章
13~1003的和
查看>>
myeclipse启动jboss报ERROR [MainDeployer] Could not create deployment
查看>>
pycharm如何新项目如何不默认创建虚拟环境(吐槽)
查看>>
Loadrunner检查点小结(很经典)
查看>>
MySQL字段类型详解
查看>>
ORACLE 的游标
查看>>
虚拟机安装的UBUNTU全屏的方法:
查看>>
java虚拟机类加载器
查看>>
ASP.NET状态管理之八(会话Session)
查看>>
background
查看>>
转载:大型网站架构演变和知识体系
查看>>
set集合
查看>>
SVN服务器的搭建和使用
查看>>
mvc中枚举的使用和绑定枚举值到DropDownListFor
查看>>
多目标跟踪的评价指标
查看>>
python 生成器
查看>>
HTTPS(SSL)详解以及PHP调用方法
查看>>
突发小事件,USB接口问题
查看>>
Nginx负载均衡配置实例详解
查看>>
L1-009. N个数求和
查看>>