NEUQ-ACM预备队第三次双周赛
1. 打字
一个无脑解法
#include<bits/stdc++.h>
using namespace std;
int a[8];
void func(char c){
if(c=='1'||c=='Q'||c=='A'||c=='Z') a[0]++;
if(c=='2'||c=='W'||c=='S'||c=='X') a[1]++;
if(c=='3'||c=='E'||c=='D'||c=='C') a[2]++;
if(c=='4'||c=='R'||c=='F'||c=='V'||c=='5'||c=='T'||c=='G'||c=='B') a[3]++;
if(c=='6'||c=='Y'||c=='H'||c=='N'||c=='7'||c=='U'||c=='J'||c=='M') a[4]++;
if(c=='8'||c=='I'||c=='K'||c==',') a[5]++;
if(c=='9'||c=='O'||c=='L'||c=='.') a[6]++;
if(c=='0'||c=='P'||c==';'||c=='/'||c=='\''||c=='['||c==']'||c=='='||c=='-') a[7]++;
}
int main(){
string s;cin>>s;
for(int i=0;i<=s.length();i++) func(s[i]);
for(int i=0;i<=7;i++) cout<<a[i]<<endl;
return 0;
}
2.
对于m根肠n个人,每个人都应该分到m/n根才是最优解那么将m根肠看成一根,每次切m/n即可
但是一刀切下去有可能正好在两根肠的交界处。此时就不能算作一刀,理论上我们需要M-1刀,但是我们还要减去无效的刀数
又因为gcd(N,M)代表着无用刀数+1 ,所以解=M-gcd(N,M)。
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
}
int main()
{
int N,M;
cin>>N>>M;
cout<<M-gcd(M,N)<<endl;
return 0;
}
3. 参加会议
在一个数轴上有n条线段,现要选取其中k条线段使得这k条线段两两没有重合部分,问最大的k为多少。
最左边的线段放什么最好?
显然放右端点最靠左的线段最好,从左向右放,右端点越小妨碍越少
其他线段放置按右端点排序,贪心放置线段,即能放就放 O2z
#include<bits/stdc++.h>
using namespace std;
struct qj
{ long int l;
long int r;
}qjj[10005];
bool vis[10005];
bool cmp(qj a,qj b) {return a.r<b.r;}
int main()
{ int m;cin>>m;
while(m--){
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>qjj[i].l>>qjj[i].r;
sort(qjj+1,qjj+1+n,cmp);
int now=0,cnt=0;
for(int i=1;i<=n;i++)
{
if(qjj[i].l>=now)
{
cnt++;
now=qjj[i].r;
}
}
cout<<cnt<<endl;}
return 0;
}
4.神秘密码
题解的巧妙递归解法
#include<bits/stdc++.h>
using namespace std;
string func()
{
string a,X;//a存储答案,X临时使用
char c;
int num;
while(cin>>c)
{
if(c=='[')//如果为左括号
{
cin>>num;
X=func();//读取后面的字符内容
while(num--) a+=X;//加上D倍的X
}
else if(c==']')//如果为右括号
{
return a;//返回a,说明此时以及读完
}
else a += c;//此处是防止没有压缩而全是字符。
}
return a; //一切都读完后,a中就存储着最终答案
}
int main()
{
cout<<func();
return 0;
}
5. 国王游戏
#include<bits/stdc++.h>
using namespace std;
struct per
{
long long r;
long long l;
};
per a[10050];
int sum[10010],ans[10010];
int lens = 1,lena;
void muti(long long x)
{
int tmp = 0;
for (int i = 1; i <= lens; i++)
sum[i] *= x;
for (int i = 1; i <= lens; i++)
{
tmp += sum[i];
sum[i] = tmp % 10;
tmp /= 10;
}//进位
while (tmp != 0)
{
lens++;
sum[lens] = tmp % 10;
tmp /= 10;
}//最后一位的进位
}
void divi(long long x) {
memset(ans, 0, sizeof(ans));
lena = lens;
int tmp = 0;
for (int i = lena; i >= 1; i--)
{
tmp *= 10;
tmp += sum[i];
if (tmp >= x)
{
ans[i] = tmp / x;
tmp %= x;
}
}
while (ans[lena] == 0)
{
if (lena == 1)
break;
lena--;
}
}
bool judge(long long x)
{
string J = to_string(x);
if (J.size() < lena) {
return true;
}
else if (J.size() == lena)
{
int cnt = lena;
while (true)
{
if (cnt == 0)return true;//其实表面俩个相等,返回真或假都可以
if (ans[cnt] > J[cnt - 1] - '0') return true;
else if (ans[cnt] == J[cnt - 1] - '0') cnt--;
else return false;
}
}
else return false;
}
int main() {
int n; cin >> n;
long long R, L; cin >> L >> R;
for (int i = 1; i <= n; i++) {
cin >> a[i].l >> a[i].r;
}
sort(a + 1, a + 1 + n, [](per a, per b) {return (a.l * a.r < b.l * b.r)||(a.l * a.r == b.l* b.r&&a.r<b.r); });
sum[1] = L;
for (int i = 1; i <= n - 1; i++) {
muti(a[i].l);
}
divi(a[n].r);
if (judge(L / a[1].r)) {
for (int i = lena; i >= 1; i--) cout << ans[i];
}
else cout << L / a[1].r;
return 0;
}