Acwing
题意: 判断两个给定字符在字母序之积意义下是否同余。
分析: 只需要分别计算出两者即可
代码如下:
#include
#include
//#define Uint unsigned int
using namespace std;
int main(void){
string a;
unsigned int n,ans_1 = 1,ans_2 = 1;
cin >> a;
n = a.length();
for(unsigned int i=0;i<n;++i){
ans_1 *= a[i]-'A'+1;}
cin >> a;
n = a.length();
for(unsigned int i=0;i<n;++i){
ans_2 *= a[i]-'A'+1;}
if(ans_1%47 == ans_2%47)
printf("GO\n");
else
printf("STAY\n");
return 0;}
Acwing
题意: 有一堆名字相互送了礼物,求最终的净收入
分析: 建立 结构体
或者 map
,处理好输入即可。要判断有没有送礼人、有没有送礼。之后需要两次循环分别计算支出和收入,为了避免被多减了,我定义了一个 bool
进行判断。题目要i求向下取整,可以先除 int
再乘 int
实现。
代码如下( struct ):
#include
using namespace std;
struct giver{
string name;
int money;
}arr[12];
string Name,names;
int n,Money,Nums;
bool flag = false;
int main(void){
cin >> n;
for(int i=1;i<=n;++i)
cin >> arr[i].name;
for(int i=1;i<=n;++i){
flag = true;
cin >> Name >> Money >> Nums;
if(!Nums || !Money)
continue;
for(int j=1;j<=Nums;++j){
cin >> names;
for(int k=1;k<=n;++k){
if(flag && arr[k].name == Name){
flag = false;
arr[k].money -= Money/Nums*Nums;}
if(arr[k].name == names)
arr[k].money += Money/Nums;}}}
for(int i=1;i<=n;++i)
cout << arr[i].name << " " << arr[i].money << endl;
return 0;}
使用(map
),是一样的思路 不过可以写得好看一点点 :
#include
map<string,int> a;
//a[name],a[s]
代码如下( map
)(其实是队长写的…):
#include
#include
#include
#include
#include
using namespace std;
const int N = 50007;
int n, m;
map<string, int>mp;
string names[N];
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
string s;
cin >> s;
names[i] = s;
mp[s] = 0;}
for(int i = 1; i <= n; ++ i){
int money, num;
string s;
cin >> s;
scanf("%d%d", &money, &num);
int remain = 0;
if(num)
remain = money - (money / num) * num;
money -= remain;
mp[s] -= money;
for(int j = 1; j <= num; ++ j){
string name;
cin >> name;
mp[name] += money / num;}}
for(int i = 1; i <= n; ++ i)
cout << names[i] << " " << mp[names[i]] << endl;
return 0;}
Acwing
题意: 计算从1900年元旦(周一)到给定年份元旦前夕之间出现过的周六、周日…在13日出现的次数
分析: 首先就是判断闰年,其次需要推算出13号所对应的星期数…如果不直接刚模拟,其实很容易得出这样的一个公式(x+a)%7+1
就是 x
经过 a
天后的星期数。接着,记得输出的顺序。
代码如下:
#include
const int days[13]={
0,31,28,31,30,31,30,31,31,30,31,30,31};
int n,count[8];
int main(){
int Day = 6;
scanf("%d",&n);
for(int i=1900;i<=1900+n-1;i++){
for(int j=1;j<=12;++j){
++count[Day];
if(j==2&&!(i%4)&&(i%100||!(i%400)))
Day = (Day+1-1)%7 + 1;
Day = (Day+days[j]-1)%7 + 1;}}
printf("%d %d ",count[6],count[7]);
for(int i=1;i<5;i++)
printf("%d ",count[i]);
printf("%d",count[5]);
return 0;}
另外,求任意给定的日期的星期数可以使用W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7
被称作基姆拉尔森计算公式
Acwing
题意: 寻找给定字符串中最长的同名字符(w被视作任意的)
分析: 顺序遍历+倒序遍历,即为所求。不过要注意到最终的答案有可能超过总长度,因此取其中较小的作为答案即可。
#include
#include
using namespace std;
int main(){
int n;
//cin >> n;
char s[405];
scanf("%d\n%[rbw]",&n,s);
int ans = 0;
for(int i=0;i<n;++i){
int b_cnt = 0;
for(int j=0; j<n;++j){
if(s[(i-j+n)%n] == 'r')
break;
else
++b_cnt;}
int r_cnt = 0;
for(int j=0;j<n;++j){
if(s[(i-j+n)%n] == 'b')
break;
else
++r_cnt;}
int left = max(b_cnt, r_cnt);
b_cnt = 0;
for(int j=1;j<=n;++j) {
if (s[(i+j)%n] == 'r')
break;
else
++b_cnt;}
r_cnt = 0;
for(int j=1;j<=n;++j){
if(s[(i+j)%n] == 'b')
break;
else
++r_cnt;}
int right = max(b_cnt, r_cnt);
ans = max(ans,left+right);}
cout << min(ans,n);
return 0;}