2018江苏程序设计大赛
A题
一道思维题,难点就在于是否能看明白题面。。。(阅读理解负十级的我流泪)
题意是:一个人,发论文,具体样子如下:
被引用次数: 0 1 2 ... n h1
发表的论文篇数: a0 a1 a2 ... an h2
问你这个人最大的被引用次数是多少(且h2>=h1)
思路:从后往前遍历即可,找到最先符合h2>=h1的就输出
代码:
#include <iostream> #include <limits> #include <queue> #include<bits/stdc++.h> #define ll long long using namespace std; #define min(a,b) (a<b ? a:b) void clear(unsigned char *pta, int size ) { while(size>0) { *pta++ = 0; size --; } } ll ar[1000000]; int main(){ int n; while(cin >>n){ // memset(ar,0,sizeof ar) ; ll sum =0 ;ll cnt = 0;int f=1; for(int i=0;i<=n;i++)cin >>ar[i]; for(int i=n;i>=0;i--){ sum+=ar[i]; if(sum >=i){ cnt = i; break; } } cout<<cnt<<endl; } return 0; }
B题
题意:你有n个小时,你可以花任意的时间x(x>0)去写一篇论文,写完之后得到的论据有a*x
之后写的论文可以通过引用自己之前写的论文使得自己的论据+1,
譬如第3篇论文写的时候可以引用前面两篇使得自己的论据+2.
引用的这位大佬的题意
官方题解
最优⽅案是各花 1 ⼩时写 n 篇论⽂。答案是 ⌊(n+a)/2⌋.
代码:
#include <iostream> #include <limits> #include <queue> #include<bits/stdc++.h> #define ll long long using namespace std; #define min(a,b) (a<b ? a:b) void clear(unsigned char *pta, int size ) { while(size>0) { *pta++ = 0; size --; } } ll ar[1000000]; int main(){ ll n , m; while(cin >>n>>m){ cout<<(n+m)/2<<endl; } return 0; }
F题
题意:让你根据那个公式排序,输出排序后的结果。
思路:按照题意模拟即可(坑在精度上,要unsigned long long 菜系)
代码:
#include <bits/stdc++.h> using namespace std; #define ll unsigned long long struct node{ ll a,b,c; int i; friend bool operator<(node p1,node p2){ if(p1.c*(p2.a + p2.b + p2.c) == p2.c*(p1.a + p1.b + p1.c)){ return p1.i > p2.i; } return p1.c*(p2.a + p2.b + p2.c) < p2.c*(p1.a + p1.b + p1.c) ; } }; int main() { priority_queue<node> q; int n; while(~scanf("%d",&n)){ ll a,b,c; for(int i=1;i<=n;i++){ scanf("%lld %lld %lld",&a,&b,&c); q.push(node{a,b,c,i}); } while(!q.empty()){ node now = q.top(); q.pop(); printf("%d",now.i); if(q.empty()){ continue ; } printf(" "); } printf("\n"); } return 0; }
G题
题意:给你三个字符数组,‘aa’,'bb','abab',然后问你对一个已知的字符串T进行操作,问是否可以改成字符串S,可以就是yes,不行就no.
思路:其实这道题是个规律题,首先通过观察样例,可以推出ab==ba,那么也就是说,只要a,b的数量都相同,就是yes,(而且因为aa,bb可增加可删除,其实只要判断a,b的奇偶就行了)否则就是no
例子:aaaabbbb,abababab
我们通过ab==ba可以吧前者转换为后者
又因为题面上有个C ,所以,这个问题就变成了c与c之间ab的奇偶问题(别忘cabba这种情况下,ab的判断)
代码:
#include<bits/stdc++.h> #define ll long long using namespace std; int main() { string s1,s2; while(cin >>s1>>s2) { int len1 = s1.size(); int len2 = s2.size(); int f =1 ; vector<int> arr,ar; arr.clear(); ar.clear(); int cnt = 0 ; int a = 0,b = 0 ; for(int i=0;i<len1;i++) { if(s1[i] != 'c'){ a ^= (s1[i]); } else{ arr.push_back(a); } } arr.push_back(a); int num = 0; a = 0 , b = 0 ; for( int i = 0; i<len2; i++ ) { if(s2[i]!='c'){ a ^= (s2[i]); } else{ ar.push_back(a); } } ar.push_back(a); if(arr == ar) cout<<"Yes"<<endl; else cout<<"No"<<endl; } }
K题
题意:给你四个数a,b,c,d。问你在a<=x<=b,c<=y<=d中,有多少对是2018的倍数
思路:因为2018的因数只有1 2 1009 2018 。所以可以使用容斥,或者同余
代码:
#include <bits/stdc++.h> using namespace std; #define ll long long ll ans[10]; int main() { ll a,b,c,d; while(~scanf("%lld %lld %lld %lld",&a,&b,&c,&d)) { ll cnt = 0; // 2018倍数 ans[1] = (b/2018 - (a-1)/2018); // 1009倍数 ans[2] = (b/1009 - (a-1)/1009 - ans[1]); // 2倍数 ans[3] = (b/2 - (a-1)/2 - ans[1]); // 1倍数 ans[4] = (b-a+1 - ans[1] - ans[2] - ans[3]); // 1倍数 ans[5] = (d - c + 1); // 2倍数 ans[6] = (d/2 - (c-1)/2); // 1009倍数 ans[7] = (d/1009 - (c-1)/1009); // 2008倍数 ans[8] = (d/2018 - (c-1)/2018); for(int i=1;i<=4;i++){ cnt += 1ll*(ans[i]*ans[i+4]); } printf("%lld\n",cnt); } return 0; }